Skip to content

Commit e7da6e5

Browse files
author
Jeremy Oursler
committed
Added multitargeting from .net framework 4.0 through .net core 3.1
Added IsInInput operator to enable Input.Contains(Property) rules Added additional example usage to cover functionality that exists but was not tested Added EF Core In Memory provider tests
1 parent f5ceac5 commit e7da6e5

File tree

7 files changed

+388
-3
lines changed

7 files changed

+388
-3
lines changed
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
// Copyright (c) 2019 Jeremy Oursler All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.ComponentModel.DataAnnotations;
7+
using System.ComponentModel.DataAnnotations.Schema;
8+
using System.Linq;
9+
using Microsoft.EntityFrameworkCore;
10+
using Microsoft.VisualStudio.TestTools.UnitTesting;
11+
12+
namespace MicroRuleEngine.Tests
13+
{
14+
[TestClass]
15+
public class InMemoryEntityFrameworkTests
16+
{
17+
private DbContextOptions<TestDbContext> options;
18+
19+
[TestMethod]
20+
public void CheckSetup()
21+
{
22+
using (var context = new TestDbContext(options))
23+
{
24+
var count = context.Students.Count();
25+
26+
Assert.AreEqual(8,
27+
count);
28+
}
29+
}
30+
31+
[TestInitialize]
32+
public void Initialize()
33+
{
34+
options = new DbContextOptionsBuilder<TestDbContext>()
35+
.UseInMemoryDatabase(Guid.NewGuid()
36+
.ToString())
37+
.Options;
38+
39+
using (var context = new TestDbContext(options))
40+
{
41+
context.Students.Add(new Student
42+
{
43+
FirstName = "Bob",
44+
LastName = "Smith",
45+
Gpa = 2.0m
46+
});
47+
48+
context.Students.Add(new Student
49+
{
50+
FirstName = "John",
51+
LastName = "Smith",
52+
Gpa = 3.5m
53+
});
54+
55+
context.Students.Add(new Student
56+
{
57+
FirstName = "Bob",
58+
LastName = "Jones",
59+
Gpa = 3.0m
60+
});
61+
62+
context.Students.Add(new Student
63+
{
64+
FirstName = "John",
65+
LastName = "Jones",
66+
Gpa = 4.0m
67+
});
68+
69+
context.Students.Add(new Student
70+
{
71+
FirstName = "Jane",
72+
LastName = "Smith",
73+
Gpa = 3.75m
74+
});
75+
76+
context.Students.Add(new Student
77+
{
78+
FirstName = "Sally",
79+
LastName = "Smith",
80+
Gpa = 1.0m
81+
});
82+
83+
context.Students.Add(new Student
84+
{
85+
FirstName = "Jane",
86+
LastName = "Jones",
87+
Gpa = 1.5m
88+
});
89+
90+
context.Students.Add(new Student
91+
{
92+
FirstName = "Sally",
93+
LastName = "Jones",
94+
Gpa = 2.5m
95+
});
96+
97+
context.SaveChanges();
98+
}
99+
}
100+
101+
[TestMethod]
102+
public void MoreComplicated()
103+
{
104+
var rule =
105+
new Rule
106+
{
107+
Operator = "OrElse",
108+
Rules = new List<Rule>
109+
{
110+
new Rule
111+
{
112+
MemberName = "FirstName",
113+
Operator = "Equal",
114+
TargetValue = "Sally"
115+
},
116+
new Rule
117+
{
118+
MemberName = "FirstName",
119+
Operator = "Equal",
120+
TargetValue = "Jane"
121+
}
122+
}
123+
};
124+
125+
var expression = MRE.ToExpression<Student>(rule, false);
126+
127+
using (var context = new TestDbContext(options))
128+
{
129+
var count = context.Students.Where(expression)
130+
.Count();
131+
132+
Assert.AreEqual(4,
133+
count);
134+
}
135+
}
136+
137+
[TestMethod]
138+
public void ReallyComplicated()
139+
{
140+
var rule =
141+
new Rule
142+
{
143+
Operator = "AndAlso",
144+
Rules = new List<Rule>
145+
{
146+
new Rule
147+
{
148+
Operator = "OrElse",
149+
Rules = new List<Rule>
150+
{
151+
new Rule
152+
{
153+
MemberName = "FirstName",
154+
Operator = "Equal",
155+
TargetValue = "Sally"
156+
},
157+
new Rule
158+
{
159+
MemberName = "FirstName",
160+
Operator = "Equal",
161+
TargetValue = "Jane"
162+
}
163+
}
164+
},
165+
new Rule
166+
{
167+
MemberName = "Gpa",
168+
Operator = "GreaterThan",
169+
TargetValue = "2.0"
170+
}
171+
}
172+
};
173+
174+
var expression = MRE.ToExpression<Student>(rule, false);
175+
176+
using (var context = new TestDbContext(options))
177+
{
178+
var count = context.Students.Where(expression)
179+
.Count();
180+
181+
Assert.AreEqual(2,
182+
count);
183+
}
184+
}
185+
186+
[TestMethod]
187+
public void SimpleRule()
188+
{
189+
var rule = new Rule
190+
{
191+
MemberName = "FirstName",
192+
Operator = "Equal",
193+
TargetValue = "Sally"
194+
};
195+
196+
var expression = MRE.ToExpression<Student>(rule, false);
197+
198+
using (var context = new TestDbContext(options))
199+
{
200+
var count = context.Students.Where(expression)
201+
.Count();
202+
203+
Assert.AreEqual(2,
204+
count);
205+
}
206+
}
207+
208+
[TestMethod]
209+
[ExpectedException(typeof(NotImplementedException))]
210+
public void SimpleRule_IncludeTryCatch()
211+
{
212+
var rule = new Rule
213+
{
214+
MemberName = "FirstName",
215+
Operator = "Equal",
216+
TargetValue = "Sally"
217+
};
218+
219+
var expression = MRE.ToExpression<Student>(rule, true);
220+
221+
using (var context = new TestDbContext(options))
222+
{
223+
var count = context.Students.Where(expression)
224+
.Count();
225+
226+
Assert.AreEqual(2,
227+
count);
228+
}
229+
}
230+
}
231+
232+
public class Student
233+
{
234+
[MaxLength(32)]
235+
public string FirstName { get; set; }
236+
237+
public decimal Gpa { get; set; }
238+
239+
[Key]
240+
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
241+
public int Id { get; set; }
242+
243+
[MaxLength(32)]
244+
public string LastName { get; set; }
245+
}
246+
247+
public class TestDbContext : DbContext
248+
{
249+
public TestDbContext(DbContextOptions<TestDbContext> options)
250+
: base(options)
251+
{
252+
}
253+
254+
public DbSet<Student> Students { get; set; }
255+
}
256+
}

MicroRuleEngine.Core.Tests/MicroRuleEngine.Core.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.6" />
1011
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
1112
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
1213
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />

MicroRuleEngine.Tests/ExampleUsage.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,106 @@ public void RegexIsMatch()//Had to add a Regex evaluator to make it feel 'Comple
212212
Assert.IsFalse(passes);
213213
}
214214

215+
[TestMethod]
216+
public void BareString()
217+
{
218+
var rule = new Rule()
219+
{
220+
Operator = "StartsWith",
221+
Inputs = new[] { "FDX" }
222+
};
223+
224+
var engine = new MRE();
225+
var childPropCheck = engine.CompileRule<string>(rule);
226+
var passes = childPropCheck("FDX 123456");
227+
Assert.IsTrue(passes);
228+
229+
230+
passes = childPropCheck("BOB 123456");
231+
Assert.IsFalse(passes);
232+
}
233+
234+
[TestMethod]
235+
public void IsInInput_SingleValue()
236+
{
237+
var value = "hello";
238+
239+
var rule = new Rule()
240+
{
241+
Operator = "IsInInput",
242+
Inputs = new List<string> { "hello" }
243+
};
244+
245+
var mre = new MRE();
246+
247+
var ruleFunc = mre.CompileRule<string>(rule);
248+
249+
Assert.IsTrue(ruleFunc(value));
250+
}
251+
252+
[TestMethod]
253+
public void IsInInput_MultiValue()
254+
{
255+
var value = "hello";
256+
257+
var rule = new Rule()
258+
{
259+
Operator = "IsInInput",
260+
Inputs = new List<string> { "hello", "World" }
261+
};
262+
263+
var mre = new MRE();
264+
265+
var ruleFunc = mre.CompileRule<string>(rule);
266+
267+
Assert.IsTrue(ruleFunc(value));
268+
}
269+
270+
[TestMethod]
271+
public void IsInInput_NoExactMatch()
272+
{
273+
var value = "world";
274+
275+
var rule = new Rule()
276+
{
277+
Operator = "IsInInput",
278+
Inputs = new List<string> { "hello", "World" }
279+
};
280+
281+
var mre = new MRE();
282+
283+
var ruleFunc = mre.CompileRule<string>(rule);
284+
285+
Assert.IsFalse(ruleFunc(value));
286+
}
287+
288+
[TestMethod]
289+
public void MemberEqualsMember()
290+
{
291+
var testObj = new MemberOperaterMemberTestObject()
292+
{
293+
Source = "bob",
294+
Target = "bob"
295+
};
296+
297+
var rule = new Rule
298+
{
299+
MemberName = "Source",
300+
Operator = "Equal",
301+
TargetValue = "*.Target"
302+
};
303+
304+
var mre = new MRE();
305+
306+
var func = mre.CompileRule<MemberOperaterMemberTestObject>(rule);
307+
308+
Assert.IsTrue(func(testObj));
309+
310+
testObj.Target = "notBob";
311+
312+
Assert.IsFalse(func(testObj));
313+
}
314+
215315
public static Order GetOrder()
216316
{
217317
Order order = new Order()

MicroRuleEngine.Tests/MicroRuleEngine.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<ItemGroup>
5858
<Compile Include="ExceptionTests.cs" />
5959
<Compile Include="IsTypeTests.cs" />
60+
<Compile Include="Models\MemberOperaterMemberTestObject.cs" />
6061
<Compile Include="NewAPI.cs" />
6162
<Compile Include="Models\Order.cs" />
6263
<Compile Include="Properties\AssemblyInfo.cs" />
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace MicroRuleEngine.Tests.Models
8+
{
9+
class MemberOperaterMemberTestObject
10+
{
11+
public string Source { get; set; }
12+
public string Target { get; set; }
13+
}
14+
}

0 commit comments

Comments
 (0)