forked from runxc1/MicroRuleEngine
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from runxc1/master
Sync with runxc1/MicroRuleEngine
- Loading branch information
Showing
14 changed files
with
1,436 additions
and
685 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,3 +23,4 @@ content | |
/ConsoleApp1-2.psess | ||
/ConsoleApp1-1.psess | ||
/MicroRuleEngine/MRE1.cs | ||
privateKey.key |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,282 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using MicroRuleEngine.Core.Tests.Models; | ||
|
||
namespace MicroRuleEngine.Tests | ||
{ | ||
/// <summary> | ||
/// Summary description for UnitTest1 | ||
/// </summary> | ||
[TestClass] | ||
public class ExampleUsage | ||
{ | ||
[TestMethod] | ||
public void ChildPropertiesOfNull() | ||
{ | ||
Order order = GetOrder(); | ||
order.Customer = null; | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Customer.Country.CountryCode", | ||
Operator = ExpressionType.Equal.ToString("g"), | ||
TargetValue = "AUS" | ||
}; | ||
MRE engine = new MRE(); | ||
var compiledRule = engine.CompileRule<Order>(rule); | ||
bool passes = compiledRule(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
public void GetAllField() | ||
{ | ||
Order order = GetOrder(); | ||
|
||
var type = order.GetType(); | ||
var members = MRE.Member.GetFields(type); | ||
Assert.IsTrue( | ||
members.Where(x=> x.Name == "Customer.Country.CountryCode" && x.PossibleOperators.Any(y=> y.Name == "StartsWith")).Any() | ||
); | ||
} | ||
|
||
[TestMethod] | ||
public void CoerceMethod() | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Codes", | ||
Operator = "Contains", | ||
TargetValue = "243", | ||
Inputs = new List<object>() { "243" } | ||
}; | ||
MRE engine = new MRE(); | ||
var compiledRule = engine.CompileRule<Order>(rule); | ||
bool passes = compiledRule(order); | ||
Assert.IsTrue(passes); | ||
|
||
order.Codes.Clear(); | ||
passes = compiledRule(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
public void ChildProperties() | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Customer.Country.CountryCode", | ||
Operator = ExpressionType.Equal.ToString("g"), | ||
TargetValue = "AUS" | ||
}; | ||
MRE engine = new MRE(); | ||
var compiledRule = engine.CompileRule<Order>(rule); | ||
bool passes = compiledRule(order); | ||
Assert.IsTrue(passes); | ||
|
||
order.Customer.Country.CountryCode = "USA"; | ||
passes = compiledRule(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
|
||
public void ConditionalLogic() | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
Operator = ExpressionType.AndAlso.ToString("g"), | ||
Rules = new List<Rule> | ||
{ | ||
new Rule { MemberName = "Customer.LastName", TargetValue = "Doe", Operator = "Equal"}, | ||
new Rule | ||
{ | ||
Operator = "Or", | ||
Rules = new List<Rule> | ||
{ | ||
new Rule { MemberName = "Customer.FirstName", TargetValue = "John", Operator = "Equal"}, | ||
new Rule { MemberName = "Customer.FirstName", TargetValue = "Jane", Operator = "Equal"} | ||
} | ||
} | ||
} | ||
}; | ||
MRE engine = new MRE(); | ||
var fakeName = engine.CompileRule<Order>(rule); | ||
bool passes = fakeName(order); | ||
Assert.IsTrue(passes); | ||
|
||
order.Customer.FirstName = "Philip"; | ||
passes = fakeName(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
public void BooleanMethods() | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
Operator = "HasItem",//The Order Object Contains a method named 'HasItem' that returns true/false | ||
Inputs = new List<object> { "Test" } | ||
}; | ||
MRE engine = new MRE(); | ||
|
||
var boolMethod = engine.CompileRule<Order>(rule); | ||
bool passes = boolMethod(order); | ||
Assert.IsTrue(passes); | ||
|
||
var item = order.Items.First(x => x.ItemCode == "Test"); | ||
item.ItemCode = "Changed"; | ||
passes = boolMethod(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
public void BooleanMethods_ByType() | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
Operator = "HasItem",//The Order Object Contains a method named 'HasItem' that returns true/false | ||
Inputs = new List<object> { "Test" } | ||
}; | ||
MRE engine = new MRE(); | ||
|
||
var boolMethod = engine.CompileRule(typeof(Order), rule); | ||
bool passes =(bool) boolMethod.DynamicInvoke(order); | ||
Assert.IsTrue(passes); | ||
|
||
var item = order.Items.First(x => x.ItemCode == "Test"); | ||
item.ItemCode = "Changed"; | ||
passes = (bool)boolMethod.DynamicInvoke(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
public void AnyOperator() | ||
{ | ||
Order order = GetOrder(); | ||
//order.Items.Any(a => a.ItemCode == "test") | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Items",// The array property | ||
Operator = "Any", | ||
Rules = new[] | ||
{ | ||
new Rule | ||
{ | ||
MemberName = "ItemCode", // the property in the above array item | ||
Operator = "Equal", | ||
TargetValue = "Test", | ||
} | ||
} | ||
}; | ||
MRE engine = new MRE(); | ||
var boolMethod = engine.CompileRule<Order>(rule); | ||
bool passes = boolMethod(order); | ||
Assert.IsTrue(passes); | ||
|
||
var item = order.Items.First(x => x.ItemCode == "Test"); | ||
item.ItemCode = "Changed"; | ||
passes = boolMethod(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
|
||
|
||
[TestMethod] | ||
public void ChildPropertyBooleanMethods() | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Customer.FirstName", | ||
Operator = "EndsWith",//Regular method that exists on string.. As a note expression methods are not available | ||
Inputs = new List<object> { "ohn" } | ||
}; | ||
MRE engine = new MRE(); | ||
var childPropCheck = engine.CompileRule<Order>(rule); | ||
bool passes = childPropCheck(order); | ||
Assert.IsTrue(passes); | ||
|
||
order.Customer.FirstName = "jane"; | ||
passes = childPropCheck(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
[TestMethod] | ||
public void ChildPropertyOfNullBooleanMethods() | ||
{ | ||
Order order = GetOrder(); | ||
order.Customer = null; | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Customer.FirstName", | ||
Operator = "EndsWith", //Regular method that exists on string.. As a note expression methods are not available | ||
Inputs = new List<object> { "ohn" } | ||
}; | ||
MRE engine = new MRE(); | ||
var childPropCheck = engine.CompileRule<Order>(rule); | ||
bool passes = childPropCheck(order); | ||
Assert.IsFalse(passes); | ||
} | ||
[TestMethod] | ||
public void RegexIsMatch()//Had to add a Regex evaluator to make it feel 'Complete' | ||
{ | ||
Order order = GetOrder(); | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Customer.FirstName", | ||
Operator = "IsMatch", | ||
TargetValue = @"^[a-zA-Z0-9]*$" | ||
}; | ||
MRE engine = new MRE(); | ||
var regexCheck = engine.CompileRule<Order>(rule); | ||
bool passes = regexCheck(order); | ||
Assert.IsTrue(passes); | ||
|
||
order.Customer.FirstName = "--NoName"; | ||
passes = regexCheck(order); | ||
Assert.IsFalse(passes); | ||
} | ||
|
||
public static Order GetOrder() | ||
{ | ||
Order order = new Order() | ||
{ | ||
OrderId = 1, | ||
Customer = new Customer() | ||
{ | ||
FirstName = "John", | ||
LastName = "Doe", | ||
Country = new Country() | ||
{ | ||
CountryCode = "AUS" | ||
} | ||
}, | ||
Items = new List<Item>() | ||
{ | ||
new Item { ItemCode = "MM23", Cost=5.25M}, | ||
new Item { ItemCode = "LD45", Cost=5.25M}, | ||
new Item { ItemCode = "Test", Cost=3.33M}, | ||
}, | ||
Codes = new List<int>() | ||
{ | ||
555, | ||
321, | ||
243 | ||
}, | ||
Total = 13.83m, | ||
OrderDate = new DateTime(1776, 7, 4), | ||
Status = Status.Open | ||
|
||
}; | ||
return order; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using EFModeling.Samples.DataSeeding; | ||
using Microsoft.Data.Sqlite; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace MicroRuleEngine.Core.Tests | ||
{ | ||
[TestClass] | ||
public class ExpressionToSQLQueryTest | ||
{ | ||
internal DbContextOptions<BloggingContext> GetDBOptions() | ||
{ | ||
var connection = new SqliteConnection("DataSource=:memory:"); | ||
connection.Open(); | ||
var options = new DbContextOptionsBuilder<BloggingContext>() | ||
.UseSqlite(connection) | ||
.Options; | ||
|
||
// Create the schema in the database | ||
using (var context = new BloggingContext(options)) | ||
{ | ||
context.Database.EnsureCreated(); | ||
} | ||
return options; | ||
} | ||
[TestMethod] | ||
public void BasicEqualityExpression() | ||
{ | ||
|
||
using (var context = new BloggingContext(GetDBOptions())) | ||
{ | ||
context.Blogs.Add(new Blog { Url = "http://test.com" }); | ||
context.SaveChanges(); | ||
|
||
var testBlog = context.Blogs.FirstOrDefault(b => b.Url == "http://test.com"); | ||
|
||
var fields = MRE.Member.GetFields(typeof(Blog)); | ||
Rule rule = new Rule | ||
{ | ||
MemberName = "Url", | ||
Operator = mreOperator.Equal.ToString("g"), | ||
TargetValue = "http://test.com" | ||
}; | ||
|
||
var blog2 = context.Blogs.Where(MRE.ToExpression<Blog>(rule, false)).FirstOrDefault(); | ||
|
||
Assert.IsTrue(testBlog.BlogId == blog2.BlogId); | ||
|
||
} | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
MicroRuleEngine.Core.Tests/MicroRuleEngine.Core.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" /> | ||
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" /> | ||
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\MicroRuleEngine\MicroRuleEngine.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.