/// <summary> /// 构造函数 /// </summary> /// <param name="variableCoercisonStrategy">默认变量值约束策略</param> /// <param name="context">公式执行上下文</param> public CSharpFormulaGlobal( IVariableCoercionStrategy variableCoercisonStrategy, FormulaEvaluatingContext context) { this.variableCoercisonStrategy = variableCoercisonStrategy; this.context = context; }
/// <summary> /// 执行表达式 /// </summary> /// <param name="formula">表达式</param> /// <param name="context">执行上下文</param> /// <returns></returns> public async Task <double> EvalAsync(string formula, FormulaEvaluatingContext context) { try { double result = await CSharpScript.EvaluateAsync <double>( formula, ScriptOptions.Default //.WithImports("System") .WithImports(availableMethodsType.Namespace) .WithReferences( typeof(System.Math).Assembly, typeof(System.Double).Assembly, typeof(Nullable <>).Assembly, typeof(CSharpFormulaGlobal).Assembly, availableMethodsType.Assembly ), new CSharpFormulaGlobal(variableCoercisonStrategy, context) ); if (Double.IsInfinity(result)) { throw new DivideByZeroException($"公式 {formula} 发生除数为零异常"); } return(result); } catch (CompilationErrorException e) when(e.Message.Contains("CS0020")) { throw new DivideByZeroException($"公式 {formula} 发生除数为零异常"); } }
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)); }
/// <summary> /// 从变量源获取原始值 /// </summary> /// <param name="variableName"></param> /// <param name="context"></param> /// <returns></returns> private async Task <double?> GetRawValue(string variableName, FormulaEvaluatingContext context) { return(await context.VariableProvider.GetVarAsync(variableName)); }