Skip to content

Commit

Permalink
feat: add custom jsonLogic string evaluators (#158)
Browse files Browse the repository at this point in the history
Signed-off-by: Florian Bacher <[email protected]>
Co-authored-by: Todd Baert <[email protected]>
  • Loading branch information
bacherfl and toddbaert authored Feb 21, 2024
1 parent d9e6b8b commit 728286c
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using JsonLogic.Net;
using Newtonsoft.Json.Linq;

namespace OpenFeature.Contrib.Providers.Flagd.Resolver.InProcess.CustomEvaluators
{
internal class StringEvaluator
{
internal object StartsWith(IProcessJsonLogic p, JToken[] args, object data)
{
return p.Apply(args[0], data).ToString().StartsWith(p.Apply(args[1], data).ToString());
}

internal object EndsWith(IProcessJsonLogic p, JToken[] args, object data)
{
return p.Apply(args[0], data).ToString().EndsWith(p.Apply(args[1], data).ToString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenFeature.Constant;
using OpenFeature.Contrib.Providers.Flagd.Resolver.InProcess.CustomEvaluators;
using OpenFeature.Error;
using OpenFeature.Model;

Expand Down Expand Up @@ -58,6 +59,11 @@ internal class JsonEvaluator
internal JsonEvaluator(string selector)
{
_selector = selector;

var stringEvaluator = new StringEvaluator();

EvaluateOperators.Default.AddOperator("starts_with", stringEvaluator.StartsWith);
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);
}

internal void Sync(FlagConfigurationUpdateType updateType, string flagConfigurations)
Expand Down
132 changes: 132 additions & 0 deletions test/OpenFeature.Contrib.Providers.Flagd.Test/StringEvaluatorTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System.Collections.Generic;
using JsonLogic.Net;
using Newtonsoft.Json.Linq;
using OpenFeature.Contrib.Providers.Flagd.Resolver.InProcess.CustomEvaluators;
using Xunit;

namespace OpenFeature.Contrib.Providers.Flagd.Test
{
public class StringEvaluatorTest
{

[Fact]
public void StartsWith()
{
// Arrange
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
var stringEvaluator = new StringEvaluator();
EvaluateOperators.Default.AddOperator("starts_with", stringEvaluator.StartsWith);

var targetingString = @"{""starts_with"": [
{
""var"": [
""color""
]
},
""yellow""
]}";

// Parse json into hierarchical structure
var rule = JObject.Parse(targetingString);

var data = new Dictionary<string, string> { { "color", "yellowcolor" } };

// Act & Assert
var result = evaluator.Apply(rule, data);
Assert.True(result.IsTruthy());

data.Clear();
data.Add("color", "blue");

result = evaluator.Apply(rule, data);
Assert.False(result.IsTruthy());
}

[Fact]
public void EndsWith()
{
// Arrange
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
var stringEvaluator = new StringEvaluator();
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);

var targetingString = @"{""ends_with"": [
{
""var"": [
""color""
]
},
""purple""
]}";

// Parse json into hierarchical structure
var rule = JObject.Parse(targetingString);

var data = new Dictionary<string, string> { { "color", "deep-purple" } };

// Act & Assert
var result = evaluator.Apply(rule, data);
Assert.True(result.IsTruthy());

data.Clear();
data.Add("color", "purple-nightmare");

result = evaluator.Apply(rule, data);
Assert.False(result.IsTruthy());
}

[Fact]
public void NonStringTypeInRule()
{
// Arrange
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
var stringEvaluator = new StringEvaluator();
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);

var targetingString = @"{""ends_with"": [
{
""var"": [
""color""
]
},
1
]}";

// Parse json into hierarchical structure
var rule = JObject.Parse(targetingString);

var data = new Dictionary<string, string> { { "color", "deep-purple" } };

// Act & Assert
var result = evaluator.Apply(rule, data);
Assert.False(result.IsTruthy());
}

[Fact]
public void NonStringTypeInData()
{
// Arrange
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
var stringEvaluator = new StringEvaluator();
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);

var targetingString = @"{""ends_with"": [
{
""var"": [
""color""
]
},
""green""
]}";

// Parse json into hierarchical structure
var rule = JObject.Parse(targetingString);

var data = new Dictionary<string, int> { { "color", 5 } };

// Act & Assert
var result = evaluator.Apply(rule, data);
Assert.False(result.IsTruthy());
}
}
}

0 comments on commit 728286c

Please sign in to comment.