Skip to content

Commit

Permalink
#31 Add support for more operators
Browse files Browse the repository at this point in the history
We now support:
* +
* ++
* -
* --
* ~
* true
* false
  • Loading branch information
Miista committed May 2, 2024
1 parent 96fe226 commit 1d6553e
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/Pose/Helpers/ShimHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static MethodBase GetMethodFromExpression(Expression expression, bool set
}
else
{
throw new NotImplementedException("Unsupported expression");
throw new UnsupportedExpressionException($"Expression (of type {expression.GetType()}) with NodeType '{expression.NodeType}' is not supported");
}
}
case ExpressionType.Call:
Expand All @@ -37,6 +37,9 @@ public static MethodBase GetMethodFromExpression(Expression expression, bool set
instanceOrType = null;
return newExpression.Constructor;
case ExpressionType.Convert:
case ExpressionType.Not:
case ExpressionType.Negate:
case ExpressionType.UnaryPlus:
var unaryExpression = expression as UnaryExpression ?? throw new Exception($"Cannot cast expression to {nameof(UnaryExpression)}");
instanceOrType = null;
return unaryExpression.Method;
Expand Down
3 changes: 2 additions & 1 deletion test/Pose.Tests/Helpers/ShimHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq.Expressions;
using System.Reflection;
using FluentAssertions;
using Pose.Exceptions;
using Pose.Helpers;
using Xunit;
// ReSharper disable PossibleNullReferenceException
Expand All @@ -19,7 +20,7 @@ public void Throws_NotImplementedException<T>(Expression<Func<T>> expression, st
Action act = () => ShimHelper.GetMethodFromExpression(expression.Body, false, out _);

// Assert
act.Should().Throw<NotImplementedException>(because: reason);
act.Should().Throw<UnsupportedExpressionException>(because: reason);
}

// ReSharper disable once InconsistentNaming
Expand Down
122 changes: 122 additions & 0 deletions test/Pose.Tests/OperatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ internal class OperatorsClass
public string Value { get; set; }

public static OperatorsClass operator +(OperatorsClass l, OperatorsClass r) => null;
public static OperatorsClass operator +(OperatorsClass l) => null;
public static OperatorsClass operator ++(OperatorsClass l) => null;
public static OperatorsClass operator -(OperatorsClass l, OperatorsClass r) => null;
public static OperatorsClass operator -(OperatorsClass l) => null;
public static OperatorsClass operator --(OperatorsClass l) => null;
public static OperatorsClass operator ~(OperatorsClass l) => null;
public static OperatorsClass operator *(OperatorsClass l, OperatorsClass r) => null;
public static OperatorsClass operator /(OperatorsClass l, OperatorsClass r) => null;
public static OperatorsClass operator %(OperatorsClass l, OperatorsClass r) => null;
Expand All @@ -26,6 +31,8 @@ internal class OperatorsClass
public static bool? operator >(OperatorsClass l, OperatorsClass r) => null;
public static bool? operator <=(OperatorsClass l, OperatorsClass r) => null;
public static bool? operator >=(OperatorsClass l, OperatorsClass r) => null;
public static bool operator true(OperatorsClass l) => false;
public static bool operator false(OperatorsClass r) => true;
}

public class Arithmetic
Expand Down Expand Up @@ -215,6 +222,121 @@ public void Can_shim_modulus_operator()
result.Should().NotBeNull(because: "the shim is configured to return a non-null value");
result.Should().Be(shimmedValue, because: "that is the value the shim is configured to return");
}

[Fact]
public void Can_shim_bitwise_complement_operator()
{
// Arrange
var shimmedValue = new OperatorsClass { Value = "Hello, World" };
var shim = Shim.Replace(() => ~Is.A<OperatorsClass>())
.With(delegate(OperatorsClass l) { return shimmedValue; });

// Act
var result = default(OperatorsClass);
PoseContext.Isolate(
() =>
{
var sut = new OperatorsClass();

result = ~sut;
}, shim);

// Assert
result.Should().NotBeNull(because: "the shim is configured to return a non-null value");
result.Should().Be(shimmedValue, because: "that is the value the shim is configured to return");
}

[Fact(Skip = "How to get the operator method from expression?")]
public void Can_shim_true_operator()
{
// Arrange
var shimmedValue = new OperatorsClass { Value = "Hello, World" };
var shim = Shim.Replace(() => ~Is.A<OperatorsClass>())
.With(delegate(OperatorsClass l) { return shimmedValue; });

// Act
var result = default(OperatorsClass);
PoseContext.Isolate(
() =>
{
var sut = new OperatorsClass();

result = sut ? shimmedValue : null;
}, shim);

// Assert
result.Should().NotBeNull(because: "the shim is configured to return a non-null value");
result.Should().Be(shimmedValue, because: "that is the value the shim is configured to return");
}

[Fact]
public void Can_shim_logical_negation_operator()
{
// Arrange
var shimmedValue = new OperatorsClass { Value = "Hello, World" };
var shim = Shim.Replace(() => ~Is.A<OperatorsClass>())
.With(delegate(OperatorsClass l) { return shimmedValue; });

// Act
var result = default(OperatorsClass);
PoseContext.Isolate(
() =>
{
var sut = new OperatorsClass();

result = ~sut;
}, shim);

// Assert
result.Should().NotBeNull(because: "the shim is configured to return a non-null value");
result.Should().Be(shimmedValue, because: "that is the value the shim is configured to return");
}

[Fact]
public void Can_shim_unary_plus_operator()
{
// Arrange
var shimmedValue = new OperatorsClass { Value = "Hello, World" };
var shim = Shim.Replace(() => +Is.A<OperatorsClass>())
.With(delegate(OperatorsClass l) { return shimmedValue; });

// Act
var result = default(OperatorsClass);
PoseContext.Isolate(
() =>
{
var sut = new OperatorsClass();

result = +sut;
}, shim);

// Assert
result.Should().NotBeNull(because: "the shim is configured to return a non-null value");
result.Should().Be(shimmedValue, because: "that is the value the shim is configured to return");
}

[Fact]
public void Can_shim_unary_minus_operator()
{
// Arrange
var shimmedValue = new OperatorsClass { Value = "Hello, World" };
var shim = Shim.Replace(() => -Is.A<OperatorsClass>())
.With(delegate(OperatorsClass l) { return shimmedValue; });

// Act
var result = default(OperatorsClass);
PoseContext.Isolate(
() =>
{
var sut = new OperatorsClass();

result = -sut;
}, shim);

// Assert
result.Should().NotBeNull(because: "the shim is configured to return a non-null value");
result.Should().Be(shimmedValue, because: "that is the value the shim is configured to return");
}
}

public class BitwiseAndShift
Expand Down

0 comments on commit 1d6553e

Please sign in to comment.