예제 #1
0
 public void InvalidArgTest3()
 {
     Assert.Throws <ArgumentException>(() =>
     {
         _ = (Child1?)DuckTyping.Implement(typeof(Child1), new Child2());
     });
 }
예제 #2
0
        public void InvalidArgTest1()
        {
            TestInterface o = null;

            TestInterface duck1 = DuckTyping.Implement <TestInterface>(o);
            TestInterface duck2 = (TestInterface)DuckTyping.Implement(typeof(TestInterface), o);
        }
예제 #3
0
 public void InvalidArgTest2()
 {
     Assert.Throws <TypeBuilderException>(() =>
     {
         _ = (NonPublicInterface?)DuckTyping.Implement(typeof(NonPublicInterface), new TestClass());
     });
 }
예제 #4
0
        public void TestInterfaceProxyMethodVariance()
        {
            Duck       duck  = new Duck();
            IInterface proxy = DuckTyping.Cast <IInterface>(duck);

            string stringValue = "String value.";
            int    intValue    = 5;

            Assert.AreEqual(stringValue, proxy.ContravariantMethod(stringValue), "Contravariant method returned wrong value.");
            Assert.IsNull(proxy.ContravariantMethod(null), "Passing and returning a null value to and from a contravariant method failed.");

            try
            {
                proxy.ContravariantMethod(new object[0]);

                Assert.Fail("Passing a non-string object through a contravariant method that takes a string parameter should have thrown an InvalidCastException.");
            }
            catch (InvalidCastException)
            { }

            try
            {
                proxy.ContravariantValueMethod(7);

                Assert.Fail("Passing a non-DateTime object through a contravariant method that takes a DateTime parameter should have thrown an InvalidCastException.");
            }
            catch (InvalidCastException)
            { }

            try
            {
                proxy.ContravariantValueMethod(null);

                Assert.Fail("Passing null through a contravariant method that takes a value type parameter should have thrown a NullReferenceException.");
            }
            catch (NullReferenceException)
            { }

            Assert.AreEqual("Method", proxy.ContravariantEnumMethod("Method"), "Contravariant method returned wrong enum value.");

            try
            {
                proxy.ContravariantEnumMethod(null);

                Assert.Fail("Passing null through a contravariant method that taks an enum parameter should have thrown a NullReferenceException.");
            }
            catch (NullReferenceException)
            { }

            Assert.AreEqual(stringValue, proxy.CovariantMethod(stringValue), "Covariant method returned wrong value.");
            Assert.IsNull(null, proxy.CovariantMethod(null), "Passing and returning a null value to and from a covariant method failed.");
            Assert.AreEqual(intValue, proxy.CovariantValueMethod(intValue), "Covariant method returned wrong int value.");
            Assert.AreEqual(AttributeTargets.Class, proxy.CovariantEnumMethod(AttributeTargets.Class), "Covariant method returned wrong enum value.");

            // Note: This next line is primarily to check whether the system handles a recursive cast properly.  If it doesn't,
            // a StackOverflowException will be thrown.
            Assert.IsTrue(proxy.Equals(proxy.VariantByRecursiveCastMethod(duck)), "Variant by recursive cast method returned wrong value.");

            Assert.AreEqual(duck, proxy.VariantByUncastMethod(proxy), "Variant by uncast method returned wrong value.");
        }
예제 #5
0
        public void TestCanCast()
        {
            Duck       duck  = new Duck();
            IInterface proxy = DuckTyping.Cast <IInterface>(duck);

            Assert.IsTrue(DuckTyping.CanCast <IInterface, Duck>(), "CanCast should have returned true.");
            Assert.IsTrue(DuckTyping.CanCast <IInterface>(duck), "CanCast should have returned true.");
            Assert.IsTrue(DuckTyping.CanCast <IInterface>(typeof(Duck)), "CanCast should have returned true.");
            Assert.IsTrue(DuckTyping.CanCast(typeof(IInterface), duck), "CanCast should have returned true.");
            Assert.IsTrue(DuckTyping.CanCast(typeof(IInterface), typeof(Duck)), "CanCast should have returned true.");

            Assert.IsTrue(DuckTyping.CanCast <Duck, IInterface>(), "CanCast should have returned true.");

            Assert.IsFalse(DuckTyping.CanCast <IFormattable>(duck), "CanCast should have returned false.");


            Assert.IsTrue(DuckTyping.CanCast <GeneralDelegate, SpecializedDelegate>(), "CanCast should have returned true.");
            Assert.IsTrue(DuckTyping.CanCast <SpecializedDelegate, GeneralDelegate>(), "CanCast should have returned true.");
            Assert.IsFalse(DuckTyping.CanCast <GeneralDelegate, EventHandler>(), "CanCast should have returned false.");


            Assert.IsTrue(DuckTyping.CanCast <AttributeTargets, string>(), "CanCast should have returned true.");
            Assert.IsTrue(DuckTyping.CanCast <string, AttributeTargets>(), "CanCast should have returned true.");
            Assert.IsFalse(DuckTyping.CanCast <AttributeTargets, DateTime>(), "CanCast should have returned false.");
        }
예제 #6
0
        public void TestInterfaceProxyToString()
        {
            Duck       duck  = new Duck();
            IInterface proxy = DuckTyping.Cast <IInterface>(duck);

            Assert.AreEqual(duck.ToString(), proxy.ToString(), "Interface proxy does not properly forward calls to ToString method.");
        }
예제 #7
0
        public void AggregateTest()
        {
            var duck = DuckTyping.Aggregate <IAggregatable>(new AggregateClass1(), new AggregateClass2());

            Assert.IsNotNull(duck);

            Assert.AreEqual(1, duck.Method1());
            Assert.AreEqual(2, duck.Method2());

            // It is still possible to get access
            // to an interface of an underlying object.
            //
            var cls2 = DuckTyping.Implement <IClass2>(duck);

            Assert.IsNotNull(cls2);
            Assert.AreEqual(2, cls2.Method2());

            // Even to switch from one aggregated object to another
            //
            var cls1 = DuckTyping.Implement <IClass1>(cls2);

            Assert.IsNotNull(cls1);
            Assert.AreEqual(1, cls1.Method1());
            Assert.AreEqual(3, cls1.Method3());
        }
예제 #8
0
        public void Test()
        {
            var duck  = DuckTyping.Implement <TestInterface> (new TestClass());
            var same  = DuckTyping.Implement <TestInterface> (duck);
            var duck2 = DuckTyping.Implement <TestInterface2>(same);

            Assert.AreSame(duck, same);

            duck.Method(33, out var value);

            Assert.AreEqual(33, value);
            Assert.AreEqual(42, duck.Method(40));
            Assert.AreEqual(22, duck.Prop);

            duck.Event += duck_Event;

            duck.CallEvent();

            Assert.AreEqual(55, eventValue);

            duck2.I2Method(33, out value);

            Assert.AreEqual(33, value);
            Assert.AreEqual(42, duck2.Method(40));
        }
예제 #9
0
        public void StructTest()
        {
            DuckTyping.AllowStaticMembers = true;
            TestInterface duck = DuckTyping.Implement <TestInterface> (new TestStruct());

            Assert.AreEqual(43, duck.Method(40));
        }
예제 #10
0
        /// <summary>
        /// Register an 'OnUpdate' method for use in the editor.
        /// This should be done in the OnAwake method of the module, and will ensure that all modules have the
        /// registered method called in order of declaration of the module in the part file.
        /// </summary>
        /// <param name="module">Module that is being registered.</param>
        /// <param name="action">Method to call</param>
        public static void RegisterOnUpdateEditor(this PartModule module, Action action)
        {
            if (!HighLogic.LoadedSceneIsEditor)
            {
                return;
            }
            Part part = module.part;
            IOnEditorUpdateUtility utility;

            foreach (MonoBehaviour c in part.GetComponents <MonoBehaviour>())
            {
                if (c.GetType().FullName == typeof(OnEditorUpdateUtility).FullName)
                {
                    utility = DuckTyping.Cast <IOnEditorUpdateUtility>(c);
                    goto found;
                }
            }

            PartModule onEditorUpdate = (PartModule)part.gameObject.AddComponent(OnEditorUpdateUtility.LatestVersion);

            utility = DuckTyping.Cast <IOnEditorUpdateUtility>(onEditorUpdate);
            part.Modules.Add(onEditorUpdate);

found:
            utility.AddOnUpdate(module, action);
        }
예제 #11
0
        public void BulkTest()
        {
            TestInterface[] ducks = DuckTyping.Implement <TestInterface, TestClass> (new Child1(), new Child2());

            Assert.IsNotEmpty(ducks);
            Assert.AreEqual(42, ducks[0].Method(40));
            Assert.AreEqual(42, ducks[1].Method(40));
        }
예제 #12
0
        public void BulkTest2()
        {
            var ducks = DuckTyping.Implement <TestInterface>(new Child1(), new Child2());

            Assert.IsNotEmpty(ducks);
            Assert.AreEqual(45, ducks[0].Method(40));
            Assert.AreEqual(50, ducks[1].Method(40));
        }
예제 #13
0
        public void StaticTest()
        {
            DuckTyping.AllowStaticMembers = true;

            var duck = DuckTyping.Implement <TestInterface, StaticClass>(new StaticClass());

            Assert.AreEqual(43, duck.Method(40));
        }
예제 #14
0
 public void BuildTimeAggregateExceptionTest()
 {
     Assert.Throws <TypeBuilderException>(() =>
     {
         // Exception here.
         //
         _ = DuckTyping.Aggregate <IOptionalInterface>(string.Empty, Guid.Empty);
     });
 }
예제 #15
0
        public void InheritanceTest2()
        {
            var duck1 = DuckTyping.Implement <TestInterface, TestClass>(new Child1());
            var duck2 = DuckTyping.Implement <TestInterface, TestClass>(new Child2());

            Assert.AreNotSame(duck1, duck2);
            Assert.AreEqual(42, duck1.Method(40));
            Assert.AreEqual(42, duck2.Method(40));
        }
예제 #16
0
 public void BuildTimeExceptionTest()
 {
     Assert.Throws <TypeBuilderException>(() =>
     {
         // Exception here.
         //
         _ = DuckTyping.Implement <IOptionalInterface>(string.Empty);
     });
 }
예제 #17
0
        public void InheritanceTest()
        {
            TestInterface duck1 = DuckTyping.Implement <TestInterface> (new Child1());
            TestInterface duck2 = DuckTyping.Implement <TestInterface> (new Child2());

            Assert.AreNotSame(duck1, duck2);
            Assert.AreEqual(45, duck1.Method(40));
            Assert.AreEqual(50, duck2.Method(40));
        }
예제 #18
0
        public void TestStaticInterfaceCast()
        {
            IAdder adder = DuckTyping.StaticCast <IAdder>(typeof(StaticAdder));

            Assert.AreEqual(4, adder.Add(2, 2));
            Assert.AreEqual(4, adder.LastTotal);

            adder.LastTotal = 15;
            Assert.AreEqual(15, adder.LastTotal);
        }
예제 #19
0
        public void TestPrepareCast()
        {
            string proxyAssemblyName = "DuckInterfaceProxy_" + typeof(IPrepareCastInterface).Name.Replace(".", "_").Replace("+", "-") + "_" + typeof(PrepareCastDuck).Name.Replace(".", "_").Replace("+", "-") + ".dll";

            Assert.IsNull(FindAssembly(proxyAssemblyName), "Proxy assembly has already been generated, so PrepareCast test cannot be done.");

            DuckTyping.PrepareCast <IPrepareCastInterface, PrepareCastDuck>();

            Assert.IsNotNull(FindAssembly(proxyAssemblyName), "PrepareCast did not result in a proxy assembly being generated.");
        }
예제 #20
0
        public void RuntimeExceptionTest()
        {
            var duck = DuckTyping.Implement <IOptionalInterface>(new TestClass());

            Assert.AreEqual(1, duck.RequiredMethod());

            // Exception here.
            //
            duck.OptionalMethod();
        }
예제 #21
0
        public void MissedMethodsAggregateTest()
        {
            var duck = DuckTyping.Aggregate <IClass1>(new Version(1, 0), Guid.NewGuid());

            Assert.That(duck, Is.Not.Null);

            // Neither System.Guid nor System.Version will ever have Method1.
            //
            Assert.That(duck.Method1(), Is.EqualTo(0));
        }
예제 #22
0
        public void InvalidArgTest1()
        {
            Assert.Throws <ArgumentNullException>(() =>
            {
                TestInterface?o = null;

                _ = DuckTyping.Implement <TestInterface>(o);
                _ = (TestInterface?)typeof(TestInterface).Implement(o);
            });
        }
예제 #23
0
        public void RuntimeAggregateExceptionTest()
        {
            var duck = DuckTyping.Aggregate <IOptionalInterface>(new TestClass(), new EmptyClass());

            Assert.AreEqual(1, duck.RequiredMethod());

            // Exception here.
            //
            duck.OptionalMethod();
        }
예제 #24
0
        public static Texture2D GetMonitorTexture(this IProgcomMonitor mon)
        {
            FieldInfo image = mMonitorType.GetField("image",
                                                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            if (image == null)
            {
                return(null);
            }
            return((Texture2D)image.GetValue(DuckTyping.Uncast(mon)));
        }
예제 #25
0
        public static IProgcomCPU CreateCPU()
        {
            LoadTypes();
            if (mCPUType == null)
            {
                throw new MissingReferenceException("Could not find ProgCom.CPUem");
            }
            object cpu = Activator.CreateInstance(mCPUType);

            return(DuckTyping.Cast <IProgcomCPU>(cpu));
        }
예제 #26
0
        public void TestInterfaceCast()
        {
            Duck duck = new Duck();

            IInterface proxy = DuckTyping.Cast <IInterface>(duck);

            Assert.IsNotNull(proxy, "DuckTyping.Cast<IInterface>(duck) return null.");
            Assert.IsTrue(proxy is IDuckProxy, "Cast did not return a proxy.");
            Assert.AreEqual(duck, ((IDuckProxy)proxy).UnwrapDuck(), "Cast returned a proxy that refers to the wrong duck object.");
            Assert.AreEqual(duck, DuckTyping.Cast <Duck>(proxy), "Reverse cast returned the wrong value.");
        }
예제 #27
0
    void Main()
    {
        MyAdder myAdder = new MyAdder();

        // Even though ICanAdd is not implemented by MyAdder,
        // we can duck cast it because it implements all the members:
        ICanAdd adder = DuckTyping.Cast <ICanAdd>(myAdder);

        // Now we can call adder as you would any ICanAdd object.
        // Transparently, this call is being forwarded to myAdder.
        int sum = adder.Add(2, 2);
    }
예제 #28
0
        public void GenericInterfaceTest()
        {
            var o     = new GenericClass <int>();
            var duck  = DuckTyping.Implement <GenericInterface <int> >(o);
            var duck2 = DuckTyping.Implement <TestInterface2>       (o);

            Assert.AreEqual(40, duck.Method(40));
            Assert.AreEqual(40, duck2.Method(40));

            duck2.I2Method(33, out var value);
            Assert.AreEqual(35, value);
        }
예제 #29
0
        public static IProgcomAssembler GetCompatibleAssembler(this IProgcomCPU cpu)
        {
            LoadTypes();
            if (mAssemblerType == null)
            {
                throw new MissingReferenceException("Could not find ProgCom.Assembler2");
            }
            object assembler = mCPUType.InvokeMember("getCompatibleAssembler",
                                                     BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                                                     null, DuckTyping.Uncast(cpu), null);

            return(DuckTyping.Cast <IProgcomAssembler>(assembler));
        }
예제 #30
0
        public void TestInterfaceProxyEquals()
        {
            Duck       duck1   = new Duck();
            Duck       duck2   = new Duck();
            IInterface proxy1a = DuckTyping.Cast <IInterface>(duck1);
            IInterface proxy1b = DuckTyping.Cast <IInterface>(duck1);
            IInterface proxy2  = DuckTyping.Cast <IInterface>(duck2);

            Assert.IsTrue(proxy1a.Equals(proxy1b), "Interface proxy does not properly forward calls to the Equals method.");
            Assert.IsTrue(!proxy1a.Equals(proxy2), "Interface proxy overrides the Equals method improperly.");

            Assert.AreEqual(proxy1a.GetHashCode(), duck1.GetHashCode(), "Interface proxy does not properly forward calls to the GetHashCode method.");
        }