Skip to content

Commit f4ec3f9

Browse files
author
Sébastien Geiser
committed
Advanced customization and hacking with inheritance
1 parent 8e87ddb commit f4ec3f9

File tree

4 files changed

+230
-62
lines changed

4 files changed

+230
-62
lines changed

CodingSeb.ExpressionEvaluator.Tests/CodingSeb.ExpressionEvaluator.Tests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
<Compile Update="TestsUtils\StructForTest2.cs">
3737
<SubType>Code</SubType>
3838
</Compile>
39+
<Compile Update="TestsUtils\XExpressionEvaluator1.cs">
40+
<SubType>Code</SubType>
41+
</Compile>
3942
</ItemGroup>
4043
<ItemGroup>
4144
<ProjectReference Include="..\CodingSeb.ExpressionEvaluator\CodingSeb.ExpressionEvaluator.csproj" />

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 165 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,8 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
14541454
{
14551455
OptionNumberParsingDecimalSeparator = ",",
14561456
}
1457-
, "0,5")
1457+
, "0,5"
1458+
, null)
14581459
.Returns(0.5)
14591460
.SetCategory("Options")
14601461
.SetCategory("Numbers Culture");
@@ -1463,7 +1464,8 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
14631464
{
14641465
OptionNumberParsingDecimalSeparator = "'",
14651466
}
1466-
, "0'5")
1467+
, "0'5"
1468+
, null)
14671469
.Returns(0.5)
14681470
.SetCategory("Options")
14691471
.SetCategory("Numbers Culture");
@@ -1472,7 +1474,8 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
14721474
{
14731475
OptionNumberParsingDecimalSeparator = ".",
14741476
}
1475-
, "0.5")
1477+
, "0.5"
1478+
, null)
14761479
.Returns(0.5)
14771480
.SetCategory("Options")
14781481
.SetCategory("Numbers Culture");
@@ -1482,7 +1485,8 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
14821485
OptionNumberParsingDecimalSeparator = ",",
14831486
OptionFunctionArgumentsSeparator = ";"
14841487
}
1485-
, "Max(0,5; 0,7)")
1488+
, "Max(0,5; 0,7)"
1489+
, null)
14861490
.Returns(0.7)
14871491
.SetCategory("Options")
14881492
.SetCategory("Numbers Culture");
@@ -1493,7 +1497,8 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
14931497
OptionNumberParsingThousandSeparator = "'",
14941498
OptionFunctionArgumentsSeparator = ";"
14951499
}
1496-
, "Max(1'200,5; 1'111'000,7)")
1500+
, "Max(1'200,5; 1'111'000,7)"
1501+
, null)
14971502
.Returns(1111000.7)
14981503
.SetCategory("Options")
14991504
.SetCategory("Numbers Culture");
@@ -1504,7 +1509,8 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
15041509
OptionNumberParsingThousandSeparator = "'",
15051510
OptionInitializersSeparator = ";"
15061511
}
1507-
, "new double[]{1'200,5; 1'111'000,7}.Max()")
1512+
, "new double[]{1'200,5; 1'111'000,7}.Max()"
1513+
, null)
15081514
.Returns(1111000.7)
15091515
.SetCategory("Options")
15101516
.SetCategory("Numbers Culture");
@@ -1514,17 +1520,19 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
15141520
#region Force Integer numbers default type
15151521

15161522
yield return new TestCaseData(new ExpressionEvaluator()
1517-
, "(130-120)/(2*250)")
1523+
, "(130-120)/(2*250)"
1524+
, null)
15181525
.Returns(0)
15191526
.SetCategory("Options")
15201527
.SetCategory("Integer Numbers default types");
15211528

15221529

15231530
yield return new TestCaseData(new ExpressionEvaluator
1524-
{
1525-
OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = false
1526-
}
1527-
, "(130-120)/(2*250)")
1531+
{
1532+
OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = false
1533+
}
1534+
, "(130-120)/(2*250)"
1535+
, null)
15281536
.Returns(0)
15291537
.SetCategory("Options")
15301538
.SetCategory("Integer Numbers default types");
@@ -1535,41 +1543,47 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
15351543
};
15361544

15371545
yield return new TestCaseData(evaluatorWithIntForceToDouble
1538-
, "(130-120)/(2*250)")
1546+
, "(130-120)/(2*250)"
1547+
, null)
15391548
.Returns(0.02)
15401549
.SetCategory("Options")
15411550
.SetCategory("Integer Numbers default types");
15421551

15431552
yield return new TestCaseData(evaluatorWithIntForceToDouble
1544-
, "Round(5.54,1)")
1553+
, "Round(5.54,1)"
1554+
, null)
15451555
.Returns(5.5)
15461556
.SetCategory("Bug")
15471557
.SetCategory("Options")
15481558
.SetCategory("Integer Numbers default types");
15491559

15501560
yield return new TestCaseData(evaluatorWithIntForceToDouble
1551-
, "Round(5.54,1, MidpointRounding.ToEven)")
1561+
, "Round(5.54,1, MidpointRounding.ToEven)"
1562+
, null)
15521563
.Returns(5.5)
15531564
.SetCategory("Bug")
15541565
.SetCategory("Options")
15551566
.SetCategory("Integer Numbers default types");
15561567

15571568
yield return new TestCaseData(evaluatorWithIntForceToDouble
1558-
, "Round(5.54,1, MidpointRounding.AwayFromZero)")
1569+
, "Round(5.54,1, MidpointRounding.AwayFromZero)"
1570+
, null)
15591571
.Returns(5.5)
15601572
.SetCategory("Bug")
15611573
.SetCategory("Options")
15621574
.SetCategory("Integer Numbers default types");
15631575

15641576
yield return new TestCaseData(evaluatorWithIntForceToDouble
1565-
, "(new string[2]).Length")
1577+
, "(new string[2]).Length"
1578+
, null)
15661579
.Returns(2)
15671580
.SetCategory("Bug")
15681581
.SetCategory("Options")
15691582
.SetCategory("Integer Numbers default types");
15701583

15711584
yield return new TestCaseData(evaluatorWithIntForceToDouble
1572-
, "(new string[] { \"Test\", \"Other\", \"Youhouhou\" })[1]")
1585+
, "(new string[] { \"Test\", \"Other\", \"Youhouhou\" })[1]"
1586+
, null)
15731587
.Returns("Other")
15741588
.SetCategory("Bug")
15751589
.SetCategory("Options")
@@ -1650,69 +1664,180 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
16501664
evaluatorOnTheFlies.PreEvaluateFunction += Evaluator_PreEvaluateFunction;
16511665

16521666
yield return new TestCaseData(evaluatorOnTheFlies
1653-
, "GetSpecifiedGenericTypesFunc<string>()[0]")
1667+
, "GetSpecifiedGenericTypesFunc<string>()[0]"
1668+
, null)
16541669
.Returns(typeof(string))
16551670
.SetCategory("On the fly func")
16561671
.SetCategory("GenericTypes");
16571672

16581673
yield return new TestCaseData(evaluatorOnTheFlies
1659-
, "GetSpecifiedGenericTypesVar<string>[0]")
1674+
, "GetSpecifiedGenericTypesVar<string>[0]"
1675+
, null)
16601676
.Returns(typeof(string))
16611677
.SetCategory("On the fly var")
16621678
.SetCategory("GenericTypes");
16631679

16641680
yield return new TestCaseData(evaluatorOnTheFlies
1665-
, "GetSpecifiedGenericTypesFunc<string, List<int>>()[1]")
1681+
, "GetSpecifiedGenericTypesFunc<string, List<int>>()[1]"
1682+
, null)
16661683
.Returns(typeof(List<int>))
16671684
.SetCategory("On the fly func")
16681685
.SetCategory("GenericTypes");
16691686

16701687
yield return new TestCaseData(evaluatorOnTheFlies
1671-
, "GetSpecifiedGenericTypesVar<string, List<int>>[1]")
1688+
, "GetSpecifiedGenericTypesVar<string, List<int>>[1]"
1689+
, null)
16721690
.Returns(typeof(List<int>))
16731691
.SetCategory("On the fly var")
16741692
.SetCategory("GenericTypes");
16751693

16761694
yield return new TestCaseData(evaluatorOnTheFlies
1677-
, "myvar1")
1695+
, "myvar1"
1696+
, null)
16781697
.Returns(5)
16791698
.SetCategory("var evaluation priority");
16801699

16811700
yield return new TestCaseData(evaluatorOnTheFlies
1682-
, "myvar2")
1701+
, "myvar2"
1702+
, null)
16831703
.Returns(3)
16841704
.SetCategory("var evaluation priority");
16851705

16861706
yield return new TestCaseData(evaluatorOnTheFlies
1687-
, "ClassForTest1.OnTheFlyStaticFunc()")
1707+
, "ClassForTest1.OnTheFlyStaticFunc()"
1708+
, null)
16881709
.Returns(8)
16891710
.SetCategory("On the fly func")
16901711
.SetCategory("Static Onthefly");
16911712

16921713
yield return new TestCaseData(evaluatorOnTheFlies
1693-
, "ClassForTest1.OnTheFlyStaticVar")
1714+
, "ClassForTest1.OnTheFlyStaticVar"
1715+
, null)
16941716
.Returns(10)
16951717
.SetCategory("On the fly var")
16961718
.SetCategory("Static Onthefly");
16971719

16981720
yield return new TestCaseData(evaluatorOnTheFlies
1699-
, "ClassForTest1.OnTheFlyStaticPreFunc()")
1721+
, "ClassForTest1.OnTheFlyStaticPreFunc()"
1722+
, null)
17001723
.Returns(15)
17011724
.SetCategory("On the fly func")
17021725
.SetCategory("Static Onthefly");
17031726

17041727
yield return new TestCaseData(evaluatorOnTheFlies
1705-
, "ClassForTest1.OnTheFlyStaticPreVar")
1728+
, "ClassForTest1.OnTheFlyStaticPreVar"
1729+
, null)
17061730
.Returns(3)
17071731
.SetCategory("On the fly var")
17081732
.SetCategory("Static Onthefly");
17091733

1734+
#endregion
1735+
1736+
#region inherits ExpressionEvaluator
1737+
1738+
ExpressionEvaluator xExpressionEvaluator1 = new XExpressionEvaluator1();
1739+
1740+
yield return new TestCaseData(xExpressionEvaluator1
1741+
, "true and true"
1742+
, null)
1743+
.Returns(true)
1744+
.SetCategory("ExpressionEvaluator extend")
1745+
.SetCategory("inherits ExpressionEvaluator")
1746+
.SetCategory("Custom operators");
1747+
1748+
yield return new TestCaseData(xExpressionEvaluator1
1749+
, "false and true"
1750+
, null)
1751+
.Returns(false)
1752+
.SetCategory("ExpressionEvaluator extend")
1753+
.SetCategory("inherits ExpressionEvaluator")
1754+
.SetCategory("Custom operators");
1755+
1756+
yield return new TestCaseData(xExpressionEvaluator1
1757+
, "false and false"
1758+
, null)
1759+
.Returns(false)
1760+
.SetCategory("ExpressionEvaluator extend")
1761+
.SetCategory("inherits ExpressionEvaluator")
1762+
.SetCategory("Custom operators");
1763+
1764+
yield return new TestCaseData(xExpressionEvaluator1
1765+
, "true and false"
1766+
, null)
1767+
.Returns(false)
1768+
.SetCategory("ExpressionEvaluator extend")
1769+
.SetCategory("inherits ExpressionEvaluator")
1770+
.SetCategory("Custom operators");
1771+
1772+
yield return new TestCaseData(xExpressionEvaluator1
1773+
, "true or true"
1774+
, null)
1775+
.Returns(true)
1776+
.SetCategory("ExpressionEvaluator extend")
1777+
.SetCategory("inherits ExpressionEvaluator")
1778+
.SetCategory("Custom operators");
1779+
1780+
yield return new TestCaseData(xExpressionEvaluator1
1781+
, "false or true"
1782+
, null)
1783+
.Returns(true)
1784+
.SetCategory("ExpressionEvaluator extend")
1785+
.SetCategory("inherits ExpressionEvaluator")
1786+
.SetCategory("Custom operators");
1787+
1788+
yield return new TestCaseData(xExpressionEvaluator1
1789+
, "false or false"
1790+
, null)
1791+
.Returns(false)
1792+
.SetCategory("ExpressionEvaluator extend")
1793+
.SetCategory("inherits ExpressionEvaluator")
1794+
.SetCategory("Custom operators");
1795+
1796+
yield return new TestCaseData(xExpressionEvaluator1
1797+
, "true or false"
1798+
, null)
1799+
.Returns(true)
1800+
.SetCategory("ExpressionEvaluator extend")
1801+
.SetCategory("inherits ExpressionEvaluator")
1802+
.SetCategory("Custom operators");
1803+
1804+
yield return new TestCaseData(xExpressionEvaluator1
1805+
, "true && true"
1806+
, new Func<Exception, object>(exception =>
1807+
{
1808+
exception.ShouldNotBeOfType<ExpressionEvaluatorSyntaxErrorException>();
1809+
1810+
return true;
1811+
}))
1812+
.Returns(true)
1813+
.SetCategory("ExpressionEvaluator extend")
1814+
.SetCategory("inherits ExpressionEvaluator")
1815+
.SetCategory("Custom operators");
1816+
1817+
1818+
yield return new TestCaseData(xExpressionEvaluator1
1819+
, "true || true"
1820+
, new Func<Exception, object> (exception =>
1821+
{
1822+
exception.ShouldNotBeOfType<ExpressionEvaluatorSyntaxErrorException>();
1823+
1824+
return true;
1825+
}))
1826+
.Returns(true)
1827+
.SetCategory("ExpressionEvaluator extend")
1828+
.SetCategory("inherits ExpressionEvaluator")
1829+
.SetCategory("Custom operators");
1830+
1831+
1832+
1833+
17101834
#endregion
17111835

17121836
#region bug resolution
17131837

17141838
yield return new TestCaseData(new ExpressionEvaluator()
1715-
, "(new List<Regex>()).GetType()")
1839+
, "(new List<Regex>()).GetType()"
1840+
, null)
17161841
.Returns(typeof(List<Regex>))
17171842
.SetCategory("Bug resolution");
17181843

@@ -1724,9 +1849,19 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
17241849

17251850

17261851
[TestCaseSource(nameof(TestCasesEvaluateWithSpecificEvaluator))]
1727-
public object EvaluateWithSpecificEvaluator(ExpressionEvaluator evaluator, string expression)
1852+
public object EvaluateWithSpecificEvaluator(ExpressionEvaluator evaluator, string expression, Func<Exception, object> inCaseOfException)
17281853
{
1729-
return evaluator.Evaluate(expression);
1854+
try
1855+
{
1856+
return evaluator.Evaluate(expression);
1857+
}
1858+
catch (Exception exception)
1859+
{
1860+
if (inCaseOfException == null)
1861+
throw;
1862+
else
1863+
return inCaseOfException(exception);
1864+
}
17301865
}
17311866

17321867
#endregion
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace CodingSeb.ExpressionEvaluator.Tests
2+
{
3+
public class XExpressionEvaluator1 : ExpressionEvaluator
4+
{
5+
protected override void Init()
6+
{
7+
operatorsDictionary.Add("and", ExpressionOperator.ConditionalAnd);
8+
operatorsDictionary.Add("or", ExpressionOperator.ConditionalOr);
9+
operatorsDictionary.Remove("&&");
10+
operatorsDictionary.Remove("||");
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)