Skip to content

Commit bb7bb0a

Browse files
authored
Merge pull request #108 from codingseb/dev
Dev
2 parents 05cc3b7 + 9f85a6b commit bb7bb0a

File tree

3 files changed

+166
-13
lines changed

3 files changed

+166
-13
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

+106
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,91 @@ public void Evaluate_ParameterTypeMismatchAutoAdapt()
16411641
.ShouldBeOfType<DateTime>();
16421642
}
16431643

1644+
/// <summary>
1645+
/// To correct #104 Extension methods do not work on context
1646+
/// work now with this keyword like in C#
1647+
/// </summary>
1648+
[Test]
1649+
[Category("Bug")]
1650+
[Category("#104")]
1651+
public void Evaluate_ExtensionMethodOnContext()
1652+
{
1653+
var evaluator = new ExpressionEvaluator
1654+
{
1655+
Context = new List<int>()
1656+
{
1657+
1,2,3,4,5
1658+
}
1659+
};
1660+
1661+
evaluator.Evaluate("this.Sum()")
1662+
.ShouldBe(15);
1663+
}
1664+
1665+
/// <summary>
1666+
/// To correct #104 Indexing do not work on context
1667+
/// work now with this keyword like in C#
1668+
/// </summary>
1669+
[Test]
1670+
[Category("Bug")]
1671+
[Category("#104")]
1672+
public void Evaluate_IndexingOnContext()
1673+
{
1674+
var evaluator = new ExpressionEvaluator
1675+
{
1676+
Context = new ClassForIndexing()
1677+
};
1678+
1679+
evaluator.Evaluate("this[\"Test\"]")
1680+
.ShouldBe("TestTest");
1681+
}
1682+
1683+
/// <summary>
1684+
/// To correct #105 Exception were not thrown when concat with string
1685+
/// </summary>
1686+
[Test]
1687+
[Category("Bug")]
1688+
[Category("#105")]
1689+
public void Evaluate_ExceptionsNotThrownWhenConcatWithString()
1690+
{
1691+
var evaluator = new ExpressionEvaluator
1692+
{
1693+
Context = new { Person = new Person2 { Name = null, Number = 1.11m } }
1694+
};
1695+
1696+
Should.Throw<NullReferenceException>(() => Console.WriteLine(evaluator.Evaluate("Person.Name.Trim() + \"Test one \"")));
1697+
Should.Throw<NullReferenceException>(() => Console.WriteLine(evaluator.Evaluate("\"Test one \" + Person.Name.Trim()")));
1698+
Should.Throw<ExpressionEvaluatorSyntaxErrorException>(() => Console.WriteLine(evaluator.Evaluate("\"Test two \" + Person.AnotherName.Trim()")));
1699+
}
1700+
1701+
/// <summary>
1702+
/// #105 Exception were not thrown when in string interpolation
1703+
/// </summary>
1704+
[Test]
1705+
[Category("Bug")]
1706+
[Category("#105")]
1707+
public void Evaluate_ExceptionsNotThrownWhenInStringInterpolation()
1708+
{
1709+
var evaluator = new ExpressionEvaluator
1710+
{
1711+
Context = new { Person = new Person2 { Name = null, Number = 1.11m } }
1712+
};
1713+
1714+
Should.Throw<NullReferenceException>(() => Console.WriteLine(evaluator.Evaluate("$\"Test one {Person.Name.Trim()}\"")));
1715+
Should.Throw<ExpressionEvaluatorSyntaxErrorException>(() => Console.WriteLine(evaluator.Evaluate("$\"Test two {Person.AnotherName.Trim()}\"")));
1716+
}
1717+
1718+
[Test]
1719+
[Category("Bug")]
1720+
[Category("MergeRequest")]
1721+
[Category("#107")]
1722+
public void Evaluate_DoubleDoubleQuotesInEscapedStringThrowException()
1723+
{
1724+
var evaluator = new ExpressionEvaluator();
1725+
1726+
evaluator.Evaluate("@\"Hello \"\" Joe\"").ShouldBe(@"Hello "" Joe");
1727+
}
1728+
16441729
#endregion
16451730

16461731
#region EvaluateWithSpecificEvaluator
@@ -1939,6 +2024,27 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
19392024
.SetCategory("On the fly var")
19402025
.SetCategory("Static Onthefly");
19412026

2027+
// MR #106
2028+
ExpressionEvaluator nullForceEvaluator = new ExpressionEvaluator
2029+
{
2030+
Variables = new Dictionary<string, object>()
2031+
{
2032+
{ "obj", new { }}
2033+
}
2034+
};
2035+
2036+
nullForceEvaluator.EvaluateVariable += (sender, e) =>
2037+
{
2038+
e.HasValue = true;
2039+
e.Value = null;
2040+
};
2041+
2042+
yield return new TestCaseData(nullForceEvaluator
2043+
, "obj.x"
2044+
, null)
2045+
.Returns(null)
2046+
.SetCategory("On the fly var");
2047+
19422048
#endregion
19432049

19442050
#region With Context object

CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
<Product>CodingSeb.ExpressionEvaluator</Product>
66
<Description>A Simple Math and Pseudo C# Expression Evaluator in One C# File. Can also execute small C# like scripts</Description>
77
<Copyright>Copyright © Coding Seb 2017</Copyright>
8-
<Version>1.4.29.0</Version>
9-
<AssemblyVersion>1.4.29.0</AssemblyVersion>
10-
<FileVersion>1.4.29.0</FileVersion>
8+
<Version>1.4.30.0</Version>
9+
<AssemblyVersion>1.4.30.0</AssemblyVersion>
10+
<FileVersion>1.4.30.0</FileVersion>
1111
<OutputPath>bin\$(Configuration)\</OutputPath>
1212
<Authors>Coding Seb</Authors>
1313
<PackageId>CodingSeb.ExpressionEvaluator</PackageId>
@@ -19,7 +19,10 @@
1919
<PackageIconUrl>https://github.com/codingseb/ExpressionEvaluator/blob/master/Icon.png?raw=true</PackageIconUrl>
2020
<PackageIcon>Icon.png</PackageIcon>
2121
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
22-
<PackageReleaseNotes>* Add Multidimensional indexing management like myStuffToIndex[1,4]</PackageReleaseNotes>
22+
<PackageReleaseNotes>* BubbleExceptionContainer now throw their exceptions when necessary and are no more concatenate in string.
23+
* The default keyword this is introduce and is automatically set on the Context object (This allow to do indexing and call extentions methods on the context object)
24+
* We can now set a variable to null in PreEvaluateVariable events
25+
* Double double quotes are now supported in escaped string to escape double quotes @""""</PackageReleaseNotes>
2326
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
2427
<RepositoryUrl>https://github.com/codingseb/ExpressionEvaluator</RepositoryUrl>
2528
</PropertyGroup>

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

+53-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/******************************************************************************************************
22
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3-
Version : 1.4.29.0
3+
Version : 1.4.30.0
44
(if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)
55
66
Author : Coding Seb
@@ -336,6 +336,7 @@ protected enum TryBlockEvaluatedState
336336
{ "null", null},
337337
{ "true", true },
338338
{ "false", false },
339+
{ "this", null }
339340
};
340341

341342
protected IDictionary<string, Func<double, double>> simpleDoubleMathFuncsDictionary = new Dictionary<string, Func<double, double>>(StringComparer.Ordinal)
@@ -872,10 +873,20 @@ protected virtual BindingFlags StaticBindingFlag
872873

873874
#region Custom and on the fly evaluation
874875

876+
private object context;
877+
875878
/// <summary>
876879
/// If set, this object is used to use it's fields, properties and methods as global variables and functions
877880
/// </summary>
878-
public object Context { get; set; }
881+
public object Context
882+
{
883+
get { return context; }
884+
set
885+
{
886+
context = value;
887+
defaultVariables["this"] = context;
888+
}
889+
}
879890

880891
private IDictionary<string, object> variables = new Dictionary<string, object>(StringComparer.Ordinal);
881892

@@ -2092,6 +2103,15 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
20922103
{
20932104
throw;
20942105
}
2106+
catch (NullReferenceException nullException)
2107+
{
2108+
stack.Push(new BubbleExceptionContainer()
2109+
{
2110+
Exception = nullException
2111+
});
2112+
2113+
return true;
2114+
}
20952115
catch (Exception ex)
20962116
{
20972117
//Transport the exception in stack.
@@ -2787,7 +2807,7 @@ protected virtual bool EvaluateIndexing(string expression, Stack<object> stack,
27872807

27882808
if(type.IsArray && OptionForceIntegerNumbersEvaluationsAsDoubleByDefault)
27892809
{
2790-
oIndexingArgs = oIndexingArgs.Select(o => o is double ? (int)o : o).ToList();
2810+
oIndexingArgs = oIndexingArgs.ConvertAll(o => o is double ? (int)o : o);
27912811
}
27922812
else
27932813
{
@@ -2924,8 +2944,16 @@ protected virtual bool EvaluateString(string expression, Stack<object> stack, re
29242944

29252945
if (expression.Substring(i)[0] == '"')
29262946
{
2927-
endOfString = true;
2928-
stack.Push(resultString.ToString());
2947+
if (expression.Substring(i).Length > 1 && expression.Substring(i)[1] == '"')
2948+
{
2949+
i += 2;
2950+
resultString.Append(@"""");
2951+
}
2952+
else
2953+
{
2954+
endOfString = true;
2955+
stack.Push(resultString.ToString());
2956+
}
29292957
}
29302958
else if (expression.Substring(i)[0] == '{')
29312959
{
@@ -2979,7 +3007,13 @@ protected virtual bool EvaluateString(string expression, Stack<object> stack, re
29793007
string beVerb = bracketCount == 1 ? "is" : "are";
29803008
throw new Exception($"{bracketCount} '}}' character {beVerb} missing in expression : [{expression}]");
29813009
}
2982-
resultString.Append(Evaluate(innerExp.ToString()));
3010+
3011+
object obj = Evaluate(innerExp.ToString());
3012+
3013+
if (obj is BubbleExceptionContainer bubbleExceptionContainer)
3014+
throw bubbleExceptionContainer.Exception;
3015+
3016+
resultString.Append(obj);
29833017
}
29843018
}
29853019
else if (expression.Substring(i, expression.Length - i)[0] == '}')
@@ -3119,14 +3153,24 @@ void EvaluateFirstPreviousUnaryOp(int j)
31193153
}
31203154
else
31213155
{
3156+
var left = (dynamic)list[i + 1];
3157+
var right = (dynamic)list[i - 1];
3158+
31223159
try
31233160
{
3124-
list[i] = operatorEvalutationsDict[eOp]((dynamic)list[i + 1], (dynamic)list[i - 1]);
3161+
list[i] = operatorEvalutationsDict[eOp](left, right);
3162+
3163+
if (left is BubbleExceptionContainer && right is string)
3164+
{
3165+
list[i] = left; //Bubble up the causing error
3166+
}
3167+
else if (right is BubbleExceptionContainer && left is string)
3168+
{
3169+
list[i] = right; //Bubble up the causing error
3170+
}
31253171
}
31263172
catch (Exception ex)
31273173
{
3128-
var left = (dynamic)list[i + 1];
3129-
var right = (dynamic)list[i - 1];
31303174
if (left is BubbleExceptionContainer)
31313175
{
31323176
list[i] = left; //Bubble up the causing error

0 commit comments

Comments
 (0)