asulwer / RulesEngine

Rules Engine with extensive Dynamic expression support
MIT License
26 stars 1 forks source link

less than/greater than with empty array fails #90

Closed JasonBoggsAtHMSdotCom closed 6 days ago

JasonBoggsAtHMSdotCom commented 6 days ago

Using less than or greater than with empty arrays fails.

using System.Collections;
using System.Dynamic;
using System.Text.Json;

using RulesEngine.Models;
using RulesEngine.Serialization;

string payload = "{\"prop\":\"someString\",\"someInt\":3,\"nest\":{\"code\":\"bar\",\"foo\":true},\"emptyArray\":[],\"populatedArray\":[{\"a\":2,\"subArray\":[{\"c\":4}]}]}";

Workflow[] workflow = [
    new() {
        WorkflowName = "Workflow",
        Rules = [
            new() {
                RuleName = "equals",
                Expression = "not emptyArray.Any(a == 3)"
            },
            new() {
                RuleName = "not equals",
                Expression = "not emptyArray.Any(a != 3)"
            },
            new() {
                RuleName = "less than",
                Expression = "not emptyArray.Any(a < 3)"
            },
            new() {
                RuleName = "greater than",
                Expression = "not emptyArray.Any(a > 3)"
            },
            new() {
                RuleName = "less than or equal",
                Expression = "not emptyArray.Any(a <= 3)"
            },
            new() {
                RuleName = "greater than or equal",
                Expression = "not emptyArray.Any(a >= 3)"
            },

        ]
    }
];

var rulesEngine = new RulesEngine.RulesEngine(workflow, new() {
    IsExpressionCaseSensitive = false,
    CustomTypes = new[] {
        typeof(IEnumerable)
    }
});

var options = new JsonSerializerOptions {
    Converters = { new ObjectAsPrimitiveConverter() },
    WriteIndented = true,
};

var target = JsonSerializer.Deserialize<ExpandoObject>(payload, options);

CancellationTokenSource cancellationTokenSource = new();
List<RuleResultTree> results = await rulesEngine.ExecuteAllRulesAsync("Workflow", cancellationTokenSource.Token, target);

Console.WriteLine(JsonSerializer.Serialize(target, options));
Console.WriteLine();

foreach(var result in results) {
    Console.WriteLine($"\t{result.IsSuccess}\t{result.Rule.Expression}");
    if(result.ExceptionMessage.Length > 0) Console.WriteLine($"\t\t\t{result.ExceptionMessage}");
}

Run this and all the last 4 comparisons all fail 1 example:

Exception while parsing expression not emptyArray.Any(a < 3) - The binary operator LessThan is not defined for the types 'RulesEngine.Models.ImplicitObject' and 'RulesEngine.Models.ImplicitObject'.