[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/orudge/ClearScript/master/ClearScriptTest/HostFunctionsTest.cs [Back]  [Original]

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.ClearScript.Util;
using Microsoft.ClearScript.V8;
using Microsoft.ClearScript.Windows;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Microsoft.ClearScript.Test
{
    [TestClass]
    [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
    public class HostFunctionsTest : ClearScriptTest
    {
        #region setup / teardown

        private ScriptEngine engine;
        private HostFunctions host;

        [TestInitialize]
        public void TestInitialize()
        {
            engine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging);
            engine.AddHostObject("host", host = new HostFunctions());
        }

        [TestCleanup]
        public void TestCleanup()
        {
            engine.Dispose();
            BaseTestCleanup();
        }

        #endregion

        #region test methods

        // ReSharper disable InconsistentNaming

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_asType()
        {
            var value = Enumerable.Range(1, 5).ToArray();
            VerifyAsType(value);
            VerifyAsType(value);
            VerifyAsType(value);
            Assert.IsNull(host.asType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_asType_Scalar()
        {
            const int value = 123;
            VerifyAsType(value);
            VerifyAsType(value);
            VerifyAsType(value);
            Assert.IsNull(host.asType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_asType_Enum()
        {
            const DayOfWeek value = DayOfWeek.Wednesday;
            VerifyAsType(value);
            VerifyAsType(value);
            VerifyAsType(value);
            VerifyAsType(value);
            Assert.IsNull(host.asType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_asType_Struct()
        {
            var value = new DateTime(2007, 5, 22, 6, 15, 43);
            VerifyAsType(value);
            VerifyAsType(value);
            VerifyAsType(value);
            Assert.IsNull(host.asType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_cast()
        {
            var value = Enumerable.Range(1, 5).ToArray();
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        [ExpectedException(typeof(RuntimeBinderException))]
        public void HostFunctions_cast_Fail()
        {
            var value = Enumerable.Range(1, 5).ToArray();
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_cast_Scalar()
        {
            const double value = 123.75;
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifyAsymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        [ExpectedException(typeof(RuntimeBinderException))]
        public void HostFunctions_cast_Scalar_Fail()
        {
            const double value = 123.75;
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_cast_Enum()
        {
            const DayOfWeek value = DayOfWeek.Wednesday;
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        [ExpectedException(typeof(RuntimeBinderException))]
        public void HostFunctions_cast_Enum_Fail()
        {
            const DayOfWeek value = DayOfWeek.Wednesday;
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_cast_Struct()
        {
            var value = new DateTime(2007, 5, 22, 6, 15, 43);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        [ExpectedException(typeof(RuntimeBinderException))]
        public void HostFunctions_cast_Struct_Fail()
        {
            var value = new DateTime(2007, 5, 22, 6, 15, 43);
            CastVerifier.VerifySymmetric(host, value);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_cast_UserDefined()
        {
            Assert.AreEqual(intVal, CastVerifier.VerifyCast(host, this));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_Action()
        {
            var fooVal = Enumerable.Range(1, 5).ToArray();
            const double barVal = Math.PI;
            const DayOfWeek bazVal = DayOfWeek.Wednesday;
            var quxVal = new DateTime(2007, 5, 22, 6, 15, 43);

            int[] foo = null;
            var bar = 0d;
            var baz = DayOfWeek.Sunday;
            var qux = DateTime.UtcNow;

            Action method = (fooArg, barArg, bazArg, quxArg) =>
            {
                foo = fooArg;
                bar = barArg;
                baz = bazArg;
                qux = quxArg;
            };

            host.del(method)(fooVal, barVal, bazVal, quxVal);
            Assert.AreEqual(fooVal, foo);
            Assert.AreEqual(barVal, bar);
            Assert.AreEqual(bazVal, baz);
            Assert.AreEqual(quxVal, qux);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_Action_0()
        {
            var methodInvoked = false;
            Action method = () => { methodInvoked = true; };
            host.del(method)();
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_Action_1()
        {
            var methodInvoked = false;
            Action method = value => { methodInvoked = value; };
            host.del(method)(true);
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_Func()
        {
            var fooVal = Enumerable.Range(1, 5).ToArray();
            const double barVal = Math.PI;
            const DayOfWeek bazVal = DayOfWeek.Wednesday;
            var quxVal = new DateTime(2007, 5, 22, 6, 15, 43);
            const int retVal = 42;

            int[] foo = null;
            var bar = 0d;
            var baz = DayOfWeek.Sunday;
            var qux = DateTime.UtcNow;

            Func method = (fooArg, barArg, bazArg, quxArg) =>
            {
                foo = fooArg;
                bar = barArg;
                baz = bazArg;
                qux = quxArg;
                return retVal;
            };

            Assert.AreEqual(retVal, host.del(method)(fooVal, barVal, bazVal, quxVal));
            Assert.AreEqual(fooVal, foo);
            Assert.AreEqual(barVal, bar);
            Assert.AreEqual(bazVal, baz);
            Assert.AreEqual(quxVal, qux);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_Func_0()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = () => { methodInvoked = true; return retVal; };
            Assert.AreEqual(retVal, host.del(method)());
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_Func_1()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = value => { methodInvoked = value; return retVal; };
            Assert.AreEqual(retVal, host.del(method)(true));
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_del_CustomDelegate()
        {
            engine.EnableAutoHostVariables = true;

            var fooVal = Enumerable.Range(1, 5).ToArray();
            const double barVal = Math.PI;
            const DayOfWeek bazVal = DayOfWeek.Wednesday;
            var quxVal = new DateTime(2007, 5, 22, 6, 15, 43);
            const int retVal = 42;

            CustomDelegateHandler method = (fooVar, fooArg, barVar, barArg, bazVar, bazArg, quxVar, quxArg, retArg) =>
            {
                fooVar.Value = fooArg;
                barVar.Value = barArg;
                bazVar.Value = bazArg;
                quxVar.Value = quxArg;
                return retArg;
            };

            int[] foo;
            var bar = 0d;
            DayOfWeek baz;
            var qux = DateTime.UtcNow;

            Assert.AreEqual(retVal, host.del(method)(out foo, fooVal, ref bar, barVal, out baz, bazVal, ref qux, quxVal, retVal));
            Assert.AreEqual(fooVal, foo);
            Assert.AreEqual(barVal, bar);
            Assert.AreEqual(bazVal, baz);
            Assert.AreEqual(quxVal, qux);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_func_0()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = () => { methodInvoked = true; return retVal; };
            Assert.AreEqual(retVal, ((Func)host.func(0, method))());
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_func_1()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = value => { methodInvoked = (bool)value; return retVal; };
            Assert.AreEqual(retVal, ((Func)host.func(1, method))(true));
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_func_2()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = (value1, value2) => { methodInvoked = (bool)value1 && (bool)value2; return retVal; };
            Assert.AreEqual(retVal, ((Func)host.func(2, method))(true, true));
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_func_0_NonGeneric()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = () => { methodInvoked = true; return retVal; };
            Assert.AreEqual(retVal, ((Func)host.func(0, method))());
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_func_1_NonGeneric()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = value => { methodInvoked = (bool)value; return retVal; };
            Assert.AreEqual(retVal, ((Func)host.func(1, method))(true));
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_func_2_NonGeneric()
        {
            var methodInvoked = false;
            const int retVal = 42;
            Func method = (value1, value2) => { methodInvoked = (bool)value1 && (bool)value2; return retVal; };
            Assert.AreEqual(retVal, ((Func)host.func(2, method))(true, true));
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isType()
        {
            var value = Enumerable.Range(1, 5).ToArray();
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsFalse(host.isType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isType_Scalar()
        {
            const int value = 123;
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsFalse(host.isType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isType_Enum()
        {
            const DayOfWeek value = DayOfWeek.Wednesday;
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsFalse(host.isType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isType_Struct()
        {
            var value = new DateTime(2007, 5, 22, 6, 15, 43);
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsTrue(host.isType(value));
            Assert.IsFalse(host.isType(value));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isTypeObj_True_TypeArg()
        {
            engine.AddHostType("Int32", typeof(int));
            Assert.IsTrue((bool)engine.Evaluate("host.isTypeObj(Int32)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isTypeObj_True_NonTypeArg()
        {
            engine.AddHostType("List", typeof(List));
            engine.AddHostType("Console", typeof(Console));
            Assert.IsTrue((bool)engine.Evaluate("host.isTypeObj(List)"));
            Assert.IsTrue((bool)engine.Evaluate("host.isTypeObj(Console)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_isTypeObj_False()
        {
            Assert.IsFalse((bool)engine.Evaluate("host.isTypeObj(5)"));
            Assert.IsFalse((bool)engine.Evaluate("host.isTypeObj({})"));
            Assert.IsFalse((bool)engine.Evaluate("host.isTypeObj(host)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newArr()
        {
            VerifyNewArr(5);
            VerifyNewArr(5, 3);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newArr_Enum()
        {
            VerifyNewArr(5);
            VerifyNewArr(5, 3);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newArr_Scalar()
        {
            VerifyNewArr(5);
            VerifyNewArr(5, 3);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newArr_Struct()
        {
            VerifyNewArr(5);
            VerifyNewArr(5, 3);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newArr_NonGeneric()
        {
            VerifyNewArr(5);
            VerifyNewArr(5, 3);
        }

        [TestMethod, TestCategory("HostFunctions")]
        [ExpectedException(typeof(ArgumentException))]
        public void HostFunctions_newArr_Fail()
        {
            VerifyNewArr();
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newObj()
        {
            Assert.IsInstanceOfType(host.newObj(), typeof(Random));
            Assert.IsInstanceOfType(host.newObj(100), typeof(Random));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newObj_Struct()
        {
            Assert.AreEqual(new Point(), host.newObj());
            Assert.AreEqual(new Point(100, 200), host.newObj(100, 200));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newObj_PropertyBag()
        {
            Assert.IsInstanceOfType(host.newObj(), typeof(PropertyBag));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newVar()
        {
            VerifyNewVar();
            VerifyNewVar(new Random(100));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newVar_Enum()
        {
            VerifyNewVar();
            VerifyNewVar(DayOfWeek.Wednesday);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newVar_Scalar()
        {
            VerifyNewVar();
            VerifyNewVar(0.125);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_newVar_Struct()
        {
            VerifyNewVar();
            VerifyNewVar(DateTime.Now);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_proc_0()
        {
            var methodInvoked = false;
            Action method = () => methodInvoked = true;
            ((Action)host.proc(0, method))();
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_proc_1()
        {
            var methodInvoked = false;
            Action method = value => methodInvoked = (bool)value;
            ((Action)host.proc(1, method))(true);
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_proc_2()
        {
            var methodInvoked = false;
            Action method = (value1, value2) => methodInvoked = (bool)value1 && (bool)value2;
            ((Action)host.proc(2, method))(true, true);
            Assert.IsTrue(methodInvoked);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_typeOf_TypeArg()
        {
            engine.AllowReflection = true;
            engine.AddHostType("Int32", typeof(int));
            Assert.AreEqual(typeof(int), engine.Evaluate("host.typeOf(Int32)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_typeOf_NonTypeArg()
        {
            engine.AllowReflection = true;
            engine.AddHostType("List", typeof(List));
            engine.AddHostType("Console", typeof(Console));
            Assert.AreEqual(typeof(List), engine.Evaluate("host.typeOf(List)"));
            Assert.AreEqual(typeof(Console), engine.Evaluate("host.typeOf(Console)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_typeOf_TypeArg_Blocked()
        {
            engine.AddHostType("Int32", typeof(int));
            TestUtil.AssertException(() => engine.Execute("host.typeOf(Int32)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_typeOf_NonTypeArg_Blocked()
        {
            engine.AddHostType("Console", typeof(Console));
            TestUtil.AssertException(() => engine.Execute("host.typeOf(Console)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_typeOf_NonType()
        {
            engine.AllowReflection = true;
            TestUtil.AssertException(() => engine.Execute("host.typeOf(5)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_flags_Unsigned()
        {
            engine.AddHostType("UnsignedFlags", HostItemFlags.PrivateAccess, typeof(UnsignedFlags));
            var result = engine.Evaluate("host.flags(UnsignedFlags.Second, UnsignedFlags.Fourth, UnsignedFlags.Sixth, UnsignedFlags.Eighth)");
            Assert.AreEqual(UnsignedFlags.Second | UnsignedFlags.Fourth | UnsignedFlags.Sixth | UnsignedFlags.Eighth, result);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_flags_Signed()
        {
            engine.AddHostType("SignedFlags", HostItemFlags.PrivateAccess, typeof(SignedFlags));
            // include Eighth member to force overflow path in host.flags()
            var result = engine.Evaluate("host.flags(SignedFlags.Second, SignedFlags.Fourth, SignedFlags.Sixth, SignedFlags.Eighth)");
            Assert.AreEqual(SignedFlags.Second | SignedFlags.Fourth | SignedFlags.Sixth | SignedFlags.Eighth, result);
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_flags_Mismatch()
        {
            engine.AddHostType("UnsignedFlags", HostItemFlags.PrivateAccess, typeof(UnsignedFlags));
            engine.AddHostType("SignedFlags", HostItemFlags.PrivateAccess, typeof(SignedFlags));
            TestUtil.AssertException(() => engine.Execute("host.flags(SignedFlags.Second, SignedFlags.Fourth, UnsignedFlags.Sixth, UnsignedFlags.Eighth)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_flags_NonFlags()
        {
            engine.AddHostType("NonFlags", HostItemFlags.PrivateAccess, typeof(NonFlags));
            TestUtil.AssertException(() => engine.Execute("host.flags(NonFlags.Second, NonFlags.Fourth, NonFlags.Sixth, NonFlags.Eighth)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toSByte()
        {
            Assert.AreEqual(Convert.ToSByte(127), engine.Evaluate("host.toSByte(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toByte()
        {
            Assert.AreEqual(Convert.ToByte(127), engine.Evaluate("host.toByte(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toInt16()
        {
            Assert.AreEqual(Convert.ToInt16(127), engine.Evaluate("host.toInt16(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toUInt16()
        {
            Assert.AreEqual(Convert.ToUInt16(127), engine.Evaluate("host.toUInt16(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toChar()
        {
            Assert.AreEqual(Convert.ToChar(127), engine.Evaluate("host.toChar(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toInt32()
        {
            Assert.AreEqual(Convert.ToInt32(127), engine.Evaluate("host.toInt32(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toUInt32()
        {
            Assert.AreEqual(Convert.ToUInt32(127), engine.Evaluate("host.toUInt32(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toInt64()
        {
            Assert.AreEqual(Convert.ToInt64(127), engine.Evaluate("host.toInt64(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toUInt64()
        {
            Assert.AreEqual(Convert.ToUInt64(127), engine.Evaluate("host.toUInt64(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toSingle()
        {
            Assert.AreEqual(Convert.ToSingle(127), engine.Evaluate("host.toSingle(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toDouble()
        {
            Assert.AreEqual(Convert.ToDouble(127), engine.Evaluate("host.toDouble(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toDecimal()
        {
            Assert.AreEqual(Convert.ToDecimal(127), engine.Evaluate("host.toDecimal(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toSByte_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions()); 
            Assert.AreEqual(Convert.ToSByte(127), engine.Evaluate("host.toSByte(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toByte_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToByte(127), engine.Evaluate("host.toByte(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toInt16_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToInt16(127), engine.Evaluate("host.toInt16(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toUInt16_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToUInt16(127), engine.Evaluate("host.toUInt16(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toChar_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToChar(127), engine.Evaluate("host.toChar(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toInt32_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToInt32(127), engine.Evaluate("host.toInt32(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toUInt32_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToUInt32(127), engine.Evaluate("host.toUInt32(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toInt64_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToInt64(127), engine.Evaluate("host.toInt64(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toUInt64_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToUInt64(127), engine.Evaluate("host.toUInt64(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toSingle_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToSingle(127), engine.Evaluate("host.toSingle(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toDouble_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToDouble(127), engine.Evaluate("host.toDouble(127)"));
        }

        [TestMethod, TestCategory("HostFunctions")]
        public void HostFunctions_toDecimal_V8()
        {
            engine.Dispose();
            engine = new V8ScriptEngine();
            engine.AddHostObject("host", new HostFunctions());
            Assert.AreEqual(Convert.ToDecimal(127), engine.Evaluate("host.toDecimal(127)"));
        }

        // ReSharper restore InconsistentNaming

        #endregion

        #region miscellaneous

        private void VerifyAsType(object value) where T : class
        {
            var hostItem = host.asType(value) as HostItem;
            Assert.IsNotNull(hostItem);
            // ReSharper disable once PossibleNullReferenceException
            Assert.AreEqual(typeof(T), hostItem.Target.Type);
            Assert.AreEqual(value, hostItem.Unwrap());
        }

        private void VerifyNewArr(params int[] lengths)
        {
            var value = (Array)host.newArr(lengths);
            Assert.IsInstanceOfType(value, typeof(T).MakeArrayType(lengths.Length));
            lengths.ForEach((length, index) => Assert.AreEqual(lengths[index], value.GetLength(index)));
        }

        private void VerifyNewArr(params int[] lengths)
        {
            VerifyNewArr(lengths);
        }

        private void VerifyNewVar()
        {
            var variable = host.newVar();
            Assert.IsInstanceOfType(variable, typeof(HostVariable));
            if (typeof(T).IsValueType)
            {
                Assert.AreEqual(default(T), ((HostVariable)variable).Value);
            }
            else
            {
                Assert.AreSame(default(T), ((HostVariable)variable).Value);
            }
        }

        private void VerifyNewVar(T initValue)
        {
            var variable = host.newVar(initValue);
            Assert.IsInstanceOfType(variable, typeof(HostVariable));
            if (typeof(T).IsValueType)
            {
                Assert.AreEqual(initValue, ((HostVariable)variable).Value);
            }
            else
            {
                Assert.AreSame(initValue, ((HostVariable)variable).Value);
            }
        }

        private const int intVal = 12345;

        public static explicit operator int(HostFunctionsTest value)
        {
            return intVal;
        }

        private static class CastVerifier
        {
            public static void VerifySymmetric(HostFunctions host, TValue value)
            {
                var result1 = VerifyCast(host, value);
                var result2 = VerifyCast(host, result1);
                Assert.AreEqual(value, result2);
            }

            public static void VerifyAsymmetric(HostFunctions host, TValue value)
            {
                var result1 = VerifyCast(host, value);
                var result2 = VerifyCast(host, result1);
                Assert.AreEqual(value.DynamicCast().DynamicCast(), result2);
            }

            public static object VerifyCast(HostFunctions host, object value)
            {
                return VerifyCast(host, value);
            }

            private static object VerifyCast(HostFunctions host, object value)
            {
                var expectedResult = value.DynamicCast();

                var result = host.cast(value);
                var hostItem = result as HostItem;
                if (hostItem != null)
                {
                    Assert.AreEqual(typeof(T), hostItem.Target.Type);
                    result = hostItem.Unwrap();
                }

                Assert.AreEqual(expectedResult, result);
                return result;
            }
        }

        private delegate int CustomDelegate(
            out int[] foo, int[] fooVal,
            ref double bar, double barVal,
            out DayOfWeek baz, DayOfWeek bazVal,
            ref DateTime qux, DateTime quxVal,
            int retVal
        );

        private delegate int CustomDelegateHandler(
            OutArg fooVar, int[] fooVal,
            RefArg barVar, double barVal,
            OutArg bazVar, DayOfWeek bazVal,
            RefArg quxVar, DateTime quxVal,
            int retVal
        );

        [Flags]
        public enum UnsignedFlags : byte
        {
            None = 0,
            First = 1 

Web Proxy Viewer  |  New URL  |  Original Page