mirror of https://github.com/sean-m/McRule.git
Added unit testing project.
parent
9478aa9bfc
commit
739ed9021c
|
@ -0,0 +1,150 @@
|
|||
namespace McRule.Tests {
|
||||
public class Filtering {
|
||||
|
||||
People[] things = new[] {
|
||||
new People("Sean", "Confused", 35, new[] {"muggle"}),
|
||||
new People("Sean", "Actor", 90, new[] {"muggle", "metallurgist"}),
|
||||
new People("Bean", "Runt", 20, new[] {"muggle", "giant"}),
|
||||
new People("Robin", "Comedian", 63, new[] {"muggle", "hilarious"}),
|
||||
new People("Tim", "Enchantor", 999, new[] {"magical", "grumpy"}),
|
||||
new People("Ragnar", "Viking", 25, new[] {"muggle", "grumpy"}),
|
||||
new People("Lars", "Viking", 30, new[] {"muggle", "grumpy"}),
|
||||
new People("Ferris", "Student", 17, new[] {"muggle"}),
|
||||
};
|
||||
|
||||
public record People(string name, string kind, int number, string[] tags = null);
|
||||
|
||||
ExpressionPolicy notSean = new ExpressionPolicy {
|
||||
Name = "Not named Sean",
|
||||
Properties = new string[] { }, // Can't do anything with this yet
|
||||
Rules = new List<ExpressionRule>
|
||||
{
|
||||
("People", "name", "!Sean").ToFilterRule(),
|
||||
}
|
||||
};
|
||||
|
||||
ExpressionPolicy eans = new ExpressionPolicy {
|
||||
Name = "eans",
|
||||
Properties = new string[] { }, // Can't do anything with this yet
|
||||
Rules = new List<ExpressionRule>
|
||||
{
|
||||
("People", "name", "*ean").ToFilterRule(),
|
||||
("People", "name", "~*EAN").ToFilterRule(),
|
||||
},
|
||||
RuleOperator = PredicateExpressionPolicyExtensions.RuleOperator.And
|
||||
};
|
||||
|
||||
ExpressionPolicy youngens = new ExpressionPolicy {
|
||||
Name = "Young folk",
|
||||
Properties = new string[] { }, // Can't do anything with this yet
|
||||
Rules = new List<ExpressionRule>
|
||||
{
|
||||
("People", "number", ">=17").ToFilterRule(),
|
||||
("People", "number", "<30").ToFilterRule(),
|
||||
},
|
||||
RuleOperator = PredicateExpressionPolicyExtensions.RuleOperator.And
|
||||
};
|
||||
|
||||
ExpressionPolicy vikings = new ExpressionPolicy {
|
||||
Name = "Vikings",
|
||||
Rules = new List<ExpressionRule>
|
||||
{
|
||||
("People", "kind", "~viking").ToFilterRule(),
|
||||
},
|
||||
RuleOperator = PredicateExpressionPolicyExtensions.RuleOperator.And
|
||||
};
|
||||
|
||||
ExpressionPolicy muggles = new ExpressionPolicy {
|
||||
Name = "Non-magic folk",
|
||||
Rules = new List<ExpressionRule>
|
||||
{
|
||||
("People", "tags", "muggle").ToFilterRule(),
|
||||
},
|
||||
RuleOperator = PredicateExpressionPolicyExtensions.RuleOperator.And
|
||||
};
|
||||
|
||||
[SetUp]
|
||||
public void Setup() {
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NegativeStringMatch() {
|
||||
var filter = notSean.GetExpression<People>()?.Compile();
|
||||
var folks = things.Where(filter);
|
||||
|
||||
Assert.Null(folks.FirstOrDefault(x => x.name == "Sean"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EndsWith() {
|
||||
// Filter should match on people who's name ends in 'ean',
|
||||
// and case insensitive ends with 'EAN'.
|
||||
var filter = eans.GetExpression<People>()?.Compile();
|
||||
var folks = things.Where(filter);
|
||||
|
||||
Assert.NotNull(folks);
|
||||
Assert.IsTrue(folks.All(x => x.name.EndsWith("ean")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CombineTwoExpressionsIntoCollection() {
|
||||
// Combine two different filters with an And
|
||||
var filter = new ExpressionRuleCollection() {
|
||||
Rules = new[] {
|
||||
youngens, vikings
|
||||
},
|
||||
RuleOperator = PredicateExpressionPolicyExtensions.RuleOperator.And
|
||||
}?.GetExpression<People>()?.Compile();
|
||||
|
||||
var folks = things.Where(filter);
|
||||
|
||||
// Match should be exclusive enough to only include Ragnar
|
||||
Assert.NotNull(folks);
|
||||
Assert.IsTrue(folks.Count() == 1);
|
||||
Assert.IsTrue(folks.FirstOrDefault()?.name == "Ragnar");
|
||||
|
||||
// Process both expressions separately to verify they
|
||||
// have different results.
|
||||
filter = youngens.GetExpression<People>()?.Compile();
|
||||
folks = things.Where(filter);
|
||||
Assert.IsTrue(folks.Count() > 1);
|
||||
|
||||
filter = vikings.GetExpression<People>()?.Compile();
|
||||
folks = things.Where(filter);
|
||||
Assert.IsTrue(folks.Count() > 1);
|
||||
|
||||
// Original compound filter with an Or predicate
|
||||
filter = new ExpressionRuleCollection() {
|
||||
Rules = new[] {
|
||||
youngens, vikings
|
||||
},
|
||||
RuleOperator = PredicateExpressionPolicyExtensions.RuleOperator.Or
|
||||
}?.GetExpression<People>()?.Compile();
|
||||
|
||||
folks = things.Where(filter);
|
||||
Assert.IsTrue(folks.Count() > 1);
|
||||
// Should include Vikings by kind and Student by number
|
||||
Assert.NotNull(folks.Where(x => x.kind == "Viking"));
|
||||
Assert.NotNull(folks.Where(x => x.kind == "Student"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void YoungPeople() {
|
||||
var filter = youngens.GetPredicateExpression<People>()?.Compile();
|
||||
var folks = things.Where(filter);
|
||||
|
||||
Assert.NotNull(folks);
|
||||
Assert.IsTrue(folks.All(x => x.number >= 17 && x.number < 30));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MugglesByTag() {
|
||||
var filter = muggles.GetExpression<People>()?.Compile();
|
||||
var folks = things.Where(filter);
|
||||
|
||||
Assert.NotNull(folks);
|
||||
Assert.IsTrue(folks.All(x => x.tags.Contains("muggle")));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\McRule\McRule.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1 @@
|
|||
global using NUnit.Framework;
|
|
@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McRule.Tests", "McRule.Tests\McRule.Tests.csproj", "{15DC72B8-E535-4E1D-82FA-A78BA540F0A4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -26,6 +28,10 @@ Global
|
|||
{0E6DF52C-D171-4E84-8D6D-BB580DF35E51}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E6DF52C-D171-4E84-8D6D-BB580DF35E51}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E6DF52C-D171-4E84-8D6D-BB580DF35E51}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{15DC72B8-E535-4E1D-82FA-A78BA540F0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{15DC72B8-E535-4E1D-82FA-A78BA540F0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{15DC72B8-E535-4E1D-82FA-A78BA540F0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{15DC72B8-E535-4E1D-82FA-A78BA540F0A4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -88,7 +88,7 @@ var thePolicy = new ExpressionPolicy {
|
|||
Properties = new string[] { }, // Can't do anything with this yet
|
||||
Rules = new List<ExpressionRule>
|
||||
{
|
||||
("Thing", "Name", "!Sean").ToFilterRule(),
|
||||
("Thing", "name", "!Sean").ToFilterRule(),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -97,7 +97,7 @@ filter.Dump();
|
|||
|
||||
new[] { new Thing("Sean", "Confused"), new Thing("Tim", "Enchantor") }.Where(filter.Compile()).Dump();
|
||||
|
||||
public record Thing(string Name, string Kind);
|
||||
public record Thing(string name, string kind, string[] tags = null);
|
||||
|
||||
record User(string first, string last, string workPhone, string homePhone, string workAddress, string agency, string[] tags = null);
|
||||
|
||||
|
|
Loading…
Reference in New Issue