public async Task DoubleThrowWhenEvalDivideByZeroTest()
        {
            var evaluator       = new CSharpExecutor(typeof(Math), new NullNotAllowedStrategy());
            var fakeVarProvider = A.Fake <IVariableProvider>();
            var context         = new FormulaEvaluatingContext
            {
                VariableProvider = fakeVarProvider
            };
            var formula = "1.0/0";

            await Assert.ThrowsAsync <DivideByZeroException>(() =>
                                                             evaluator.EvalAsync(formula, context)
                                                             );
        }
        public async Task EvalNonExistingVariableTest()
        {
            var evaluator       = new CSharpExecutor(typeof(Math), new NullNotAllowedStrategy());
            var fakeVarProvider = A.Fake <IVariableProvider>();

            A.CallTo(() => fakeVarProvider.GetVarAsync("a"))
            .Returns(Task.FromResult <double?>(null));
            var context = new FormulaEvaluatingContext
            {
                VariableProvider = fakeVarProvider
            };
            var formula = "await Var(\"a\") + await Var(\"b\") + 3";

            await Assert.ThrowsAsync <CoerceVariableFailException>(() =>
                                                                   evaluator.EvalAsync(formula, context)
                                                                   );
        }
        public async Task IntThrowWhenEvalDivideByZeroTest()
        {
            var evaluator       = new CSharpExecutor(typeof(Math), new NullNotAllowedStrategy());
            var fakeVarProvider = A.Fake <IVariableProvider>();

            A.CallTo(() => fakeVarProvider.GetVarAsync("a"))
            .Returns(0);
            var context = new FormulaEvaluatingContext
            {
                VariableProvider = fakeVarProvider
            };
            var formula = "1/await Var(\"a\")";

            await Assert.ThrowsAsync <DivideByZeroException>(() =>
                                                             evaluator.EvalAsync(formula, context)
                                                             );
        }
        public async Task EvalExpressionTest(string formula, double expected)
        {
            //var evaluator = new CSharpExecutor(new NullNotAllowedStrategy());
            //var fakeVarProvider = A.Fake<IVariableProvider>();
            //A.CallTo(() => fakeVarProvider.GetVarAsync("a", A<VariableCriteria>.That.IsNotNull()))
            //    .Returns(10);
            //A.CallTo(() => fakeVarProvider.GetVarAsync("参数", A<VariableCriteria>.That.IsNotNull()))
            //    .Returns(20);
            //A.CallTo(() => fakeVarProvider.GetVarAsync("PI", A<VariableCriteria>.That.IsNotNull()))
            //    .Returns(Math.PI);
            //var context = new FormulaEvaluatingContext
            //{
            //    VariableProvider = fakeVarProvider,
            //    DistrictIndicatorResolver = A.Fake<IDistrictIndicatorResolver>(),
            //};

            //var actual = await evaluator.EvalAsync(formula, context);

            //Assert.Equal(expected, actual);

            var evaluator       = new CSharpExecutor(typeof(Math), new NullNotAllowedStrategy());
            var fakeVarProvider = A.Fake <IVariableProvider>();

            A.CallTo(() => fakeVarProvider.GetVarAsync("a"))
            .Returns(10);
            A.CallTo(() => fakeVarProvider.GetVarAsync("参数"))
            .Returns(20);
            A.CallTo(() => fakeVarProvider.GetVarAsync("PI"))
            .Returns(Math.PI);
            var context = new FormulaEvaluatingContext
            {
                VariableProvider = fakeVarProvider,
                //DistrictIndicatorResolver = A.Fake<IDistrictIndicatorResolver>(),
            };

            var actual = await evaluator.EvalAsync(formula, context);

            Assert.Equal(expected, actual);
        }
        /// <summary>
        /// 执行表达式
        /// </summary>
        /// <param name="formula">表达式</param>
        /// <param name="context">执行上下文</param>
        /// <returns></returns>
        public Task <double> EvalAsync(string formula, FormulaEvaluatingContext context)
        {
            var scriptToExecute = interpreter.Interpret(formula, availableMethodsType);

            return(executor.EvalAsync(scriptToExecute, context));
        }