Skip to content

Commit 728286c

Browse files
bacherfltoddbaert
andauthored
feat: add custom jsonLogic string evaluators (#158)
Signed-off-by: Florian Bacher <[email protected]> Co-authored-by: Todd Baert <[email protected]>
1 parent d9e6b8b commit 728286c

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using JsonLogic.Net;
3+
using Newtonsoft.Json.Linq;
4+
5+
namespace OpenFeature.Contrib.Providers.Flagd.Resolver.InProcess.CustomEvaluators
6+
{
7+
internal class StringEvaluator
8+
{
9+
internal object StartsWith(IProcessJsonLogic p, JToken[] args, object data)
10+
{
11+
return p.Apply(args[0], data).ToString().StartsWith(p.Apply(args[1], data).ToString());
12+
}
13+
14+
internal object EndsWith(IProcessJsonLogic p, JToken[] args, object data)
15+
{
16+
return p.Apply(args[0], data).ToString().EndsWith(p.Apply(args[1], data).ToString());
17+
}
18+
}
19+
}

Diff for: src/OpenFeature.Contrib.Providers.Flagd/Resolver/InProcess/JsonEvaluator.cs

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Newtonsoft.Json;
88
using Newtonsoft.Json.Linq;
99
using OpenFeature.Constant;
10+
using OpenFeature.Contrib.Providers.Flagd.Resolver.InProcess.CustomEvaluators;
1011
using OpenFeature.Error;
1112
using OpenFeature.Model;
1213

@@ -58,6 +59,11 @@ internal class JsonEvaluator
5859
internal JsonEvaluator(string selector)
5960
{
6061
_selector = selector;
62+
63+
var stringEvaluator = new StringEvaluator();
64+
65+
EvaluateOperators.Default.AddOperator("starts_with", stringEvaluator.StartsWith);
66+
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);
6167
}
6268

6369
internal void Sync(FlagConfigurationUpdateType updateType, string flagConfigurations)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
using System.Collections.Generic;
2+
using JsonLogic.Net;
3+
using Newtonsoft.Json.Linq;
4+
using OpenFeature.Contrib.Providers.Flagd.Resolver.InProcess.CustomEvaluators;
5+
using Xunit;
6+
7+
namespace OpenFeature.Contrib.Providers.Flagd.Test
8+
{
9+
public class StringEvaluatorTest
10+
{
11+
12+
[Fact]
13+
public void StartsWith()
14+
{
15+
// Arrange
16+
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
17+
var stringEvaluator = new StringEvaluator();
18+
EvaluateOperators.Default.AddOperator("starts_with", stringEvaluator.StartsWith);
19+
20+
var targetingString = @"{""starts_with"": [
21+
{
22+
""var"": [
23+
""color""
24+
]
25+
},
26+
""yellow""
27+
]}";
28+
29+
// Parse json into hierarchical structure
30+
var rule = JObject.Parse(targetingString);
31+
32+
var data = new Dictionary<string, string> { { "color", "yellowcolor" } };
33+
34+
// Act & Assert
35+
var result = evaluator.Apply(rule, data);
36+
Assert.True(result.IsTruthy());
37+
38+
data.Clear();
39+
data.Add("color", "blue");
40+
41+
result = evaluator.Apply(rule, data);
42+
Assert.False(result.IsTruthy());
43+
}
44+
45+
[Fact]
46+
public void EndsWith()
47+
{
48+
// Arrange
49+
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
50+
var stringEvaluator = new StringEvaluator();
51+
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);
52+
53+
var targetingString = @"{""ends_with"": [
54+
{
55+
""var"": [
56+
""color""
57+
]
58+
},
59+
""purple""
60+
]}";
61+
62+
// Parse json into hierarchical structure
63+
var rule = JObject.Parse(targetingString);
64+
65+
var data = new Dictionary<string, string> { { "color", "deep-purple" } };
66+
67+
// Act & Assert
68+
var result = evaluator.Apply(rule, data);
69+
Assert.True(result.IsTruthy());
70+
71+
data.Clear();
72+
data.Add("color", "purple-nightmare");
73+
74+
result = evaluator.Apply(rule, data);
75+
Assert.False(result.IsTruthy());
76+
}
77+
78+
[Fact]
79+
public void NonStringTypeInRule()
80+
{
81+
// Arrange
82+
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
83+
var stringEvaluator = new StringEvaluator();
84+
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);
85+
86+
var targetingString = @"{""ends_with"": [
87+
{
88+
""var"": [
89+
""color""
90+
]
91+
},
92+
1
93+
]}";
94+
95+
// Parse json into hierarchical structure
96+
var rule = JObject.Parse(targetingString);
97+
98+
var data = new Dictionary<string, string> { { "color", "deep-purple" } };
99+
100+
// Act & Assert
101+
var result = evaluator.Apply(rule, data);
102+
Assert.False(result.IsTruthy());
103+
}
104+
105+
[Fact]
106+
public void NonStringTypeInData()
107+
{
108+
// Arrange
109+
var evaluator = new JsonLogicEvaluator(EvaluateOperators.Default);
110+
var stringEvaluator = new StringEvaluator();
111+
EvaluateOperators.Default.AddOperator("ends_with", stringEvaluator.EndsWith);
112+
113+
var targetingString = @"{""ends_with"": [
114+
{
115+
""var"": [
116+
""color""
117+
]
118+
},
119+
""green""
120+
]}";
121+
122+
// Parse json into hierarchical structure
123+
var rule = JObject.Parse(targetingString);
124+
125+
var data = new Dictionary<string, int> { { "color", 5 } };
126+
127+
// Act & Assert
128+
var result = evaluator.Apply(rule, data);
129+
Assert.False(result.IsTruthy());
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)