Skip to content

Commit

Permalink
Merge pull request #67 from bijington/issue-64-null-used-in-compariso…
Browse files Browse the repository at this point in the history
…n-is-inconsistent

Comparisons now correctly handle nulls and are consistent with .NET. …
  • Loading branch information
bijington authored Jul 14, 2020
2 parents 5f5caa7 + 4c494c4 commit 8831805
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 615 deletions.
21 changes: 0 additions & 21 deletions Source/CSharp/Expressive/Expressive.Tests/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,27 +163,6 @@ public void RelationalTests()
// Dates can be parsed to string.
Assert.AreEqual(true, new Expression("[date1] == '2016-01-01'").Evaluate(new Dictionary<string, object> { ["date1"] = new DateTime(2016, 01, 01) }));
Assert.AreEqual(true, new Expression("[date1] == '01/01/2016 00:00:00'").Evaluate(new Dictionary<string, object> { ["date1"] = new DateTime(2016, 01, 01) }));

// Null safety
Assert.AreEqual(true, new Expression("[number1] == null").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(false, new Expression("[number1] == null").Evaluate(new Dictionary<string, object> { ["number1"] = 2 }));
Assert.AreEqual(false, new Expression("[number1] != null").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(true, new Expression("[number1] != null").Evaluate(new Dictionary<string, object> { ["number1"] = 2 }));
Assert.AreEqual(true, new Expression("[number1] <> 2").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("[number1] >= 2").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("[number1] > 2").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("[number1] <= 2").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("[number1] < 2").Evaluate(new Dictionary<string, object> { ["number1"] = null }));

Assert.AreEqual(true, new Expression("null == [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(false, new Expression("null == [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = 2 }));
Assert.AreEqual(false, new Expression("null != [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(true, new Expression("null != [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = 2 }));
Assert.AreEqual(true, new Expression("2 <> [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("2 >= [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("2 > [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("2 <= [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
Assert.AreEqual(null, new Expression("2 < [number1]").Evaluate(new Dictionary<string, object> { ["number1"] = null }));
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,89 +1,39 @@
using System.Collections.Generic;
using Expressive.Expressions;
using Expressive.Expressions.Binary.Relational;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using NUnit.Framework;

namespace Expressive.Tests.Expressions.Binary.Relational
{
[TestClass]
public class EqualExpressionTests
public static class EqualExpressionTests
{
[TestMethod]
public void TestBothNull()
[TestCase(null, null, true)]
[TestCase(5, 5, true)]
[TestCase(5, 2, false)]
[TestCase(2, 5, false)]
[TestCase(null, "abc", false)]
[TestCase("abc", null, false)]
[TestCase("abc", "abc", true)]
[TestCase(null, false, false)]
[TestCase(false, null, false)]
[TestCase(true, false, false)]
[TestCase(true, true, true)]
[TestCase(false, false, true)]
[TestCase(false, true, false)]
[TestCase(1.001, 1, false)]
[TestCase(1, 1.001, false)]
[TestCase(1.001, 1.001, true)]
[TestCase(1, 1.00, true)]
[TestCase(1.00, 1, true)]
public static void TestEvaluate(object lhs, object rhs, object expectedValue)
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == lhs),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == rhs),
new Context(ExpressiveOptions.None));

Assert.AreEqual(true, expression.Evaluate(null));
}

[TestMethod]
public void TestEqual()
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
new Context(ExpressiveOptions.None));

Assert.AreEqual(true, expression.Evaluate(null));
}

[TestMethod]
public void TestLeftNull()
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)"abc"),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
}

[TestMethod]
public void TestNotEqual()
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)2),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
}

[TestMethod]
public void TestRightNull()
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)false),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
}

[TestMethod]
public void TestIntFloatUnequal()
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1.001),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
}

[TestMethod]
public void TestIntFloatEqual()
{
var expression = new EqualExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1.00),
new Context(ExpressiveOptions.None));

Assert.AreEqual(true, expression.Evaluate(null));
Assert.That(expression.Evaluate(null), Is.EqualTo(expectedValue));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,102 +1,39 @@
using System.Collections.Generic;
using Expressive.Expressions;
using Expressive.Expressions.Binary.Relational;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using NUnit.Framework;

namespace Expressive.Tests.Expressions.Binary.Relational
{
[TestClass]
public class GreaterThanExpressionTests
public static class GreaterThanExpressionTests
{
[TestMethod]
public void TestBothNull()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
new Context(ExpressiveOptions.None));

Assert.AreEqual(null, expression.Evaluate(null));
}

[TestMethod]
public void TestEqual()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
}

[TestMethod]
public void TestGreaterThan()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)2),
new Context(ExpressiveOptions.None));

Assert.AreEqual(true, expression.Evaluate(null));
}

[TestMethod]
public void TestLeftNull()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)"abc"),
new Context(ExpressiveOptions.None));

Assert.AreEqual(null, expression.Evaluate(null));
}

[TestMethod]
public void TestLessThan()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)2),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)5),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
}

[TestMethod]
public void TestRightNull()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)false),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)null),
new Context(ExpressiveOptions.None));

Assert.AreEqual(null, expression.Evaluate(null));
}

[TestMethod]
public void TestIntFloatTrue()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1.001),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1),
new Context(ExpressiveOptions.None));

Assert.AreEqual(true, expression.Evaluate(null));
}

[TestMethod]
public void TestIntFloatFalse()
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == (object)1.001),
new Context(ExpressiveOptions.None));

Assert.AreEqual(false, expression.Evaluate(null));
[TestCase(null, null, false)]
[TestCase(5, 5, false)]
[TestCase(5, 2, true)]
[TestCase(2, 5, false)]
[TestCase(null, "abc", false)]
[TestCase("abc", null, true)]
[TestCase("abc", "abc", false)]
[TestCase(null, false, false)]
[TestCase(false, null, true)]
[TestCase(true, false, true)]
[TestCase(true, true, false)]
[TestCase(false, false, false)]
[TestCase(false, true, false)]
[TestCase(1.001, 1, true)]
[TestCase(1, 1.001, false)]
[TestCase(1.001, 1.001, false)]
[TestCase(1, 1.00, false)]
[TestCase(1.00, 1, false)]
public static void TestEvaluate(object lhs, object rhs, object expectedValue)
{
var expression = new GreaterThanExpression(
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == lhs),
Mock.Of<IExpression>(e => e.Evaluate(It.IsAny<IDictionary<string, object>>()) == rhs),
new Context(ExpressiveOptions.None));

Assert.That(expression.Evaluate(null), Is.EqualTo(expectedValue));
}


}
}
Loading

0 comments on commit 8831805

Please sign in to comment.