Updated to allow for Not operator

pull/83/head
David Hall 2019-07-26 14:59:39 -06:00
parent e0aa2e8781
commit 288d622f1d
1 changed files with 104 additions and 35 deletions

View File

@ -3,13 +3,28 @@ using System;
namespace Vanara.PInvoke.Tests namespace Vanara.PInvoke.Tests
{ {
public static class ResultIs public abstract class ResultIs // : NUnit.Framework.Is
{ {
public static FailureConstraint Failure => new FailureConstraint(); public static FailureConstraint Failure => new FailureConstraint();
public static MyConstraintExpression Not => MyConstraintExpression.Not;
public static SuccessfulConstraint Successful => new SuccessfulConstraint(); public static SuccessfulConstraint Successful => new SuccessfulConstraint();
public static ValueConstraint Value(object value) => new ValueConstraint(value);
public static ValidHandleConstraint ValidHandle => new ValidHandleConstraint(); public static ValidHandleConstraint ValidHandle => new ValidHandleConstraint();
public static FailureConstraint FailureCode(object expectedError) => new FailureConstraint(expectedError); public static FailureConstraint FailureCode(object expectedError) => new FailureConstraint(expectedError);
public static ValueConstraint Value(object value) => new ValueConstraint(value);
}
public class MyConstraintExpression
{
private OpConstraint.Op op;
private MyConstraintExpression(OpConstraint.Op _op) => op = _op;
public static MyConstraintExpression Not => new MyConstraintExpression(OpConstraint.Op.Not);
public ValidHandleConstraint ValidHandle => new ValidHandleConstraint(op);
public ValueConstraint Value(object value) => new ValueConstraint(value, op);
} }
public class FailureConstraint : Constraint public class FailureConstraint : Constraint
@ -20,15 +35,19 @@ namespace Vanara.PInvoke.Tests
{ {
case null: case null:
break; break;
case int i: case int i:
Expected = new Win32Error(i); Expected = new Win32Error(i);
break; break;
case uint i: case uint i:
Expected = new HRESULT(i); Expected = new HRESULT(i);
break; break;
case IErrorProvider iep: case IErrorProvider iep:
Expected = iep; Expected = iep;
break; break;
default: default:
throw new ArgumentException(); throw new ArgumentException();
} }
@ -149,54 +168,104 @@ namespace Vanara.PInvoke.Tests
} }
} }
public class ValueConstraint : Constraint public abstract class OpConstraint : Constraint
{
public enum Op
{
None = 0,
Not = 1
}
protected Op AppliedOp { get; }
protected OpConstraint(Op op) => AppliedOp = op;
protected string Prefix
{
get
{
switch (AppliedOp)
{
case Op.Not:
return "Not ";
default:
return "";
}
}
}
}
public class ValidHandleConstraint : OpConstraint
{
public ValidHandleConstraint(OpConstraint.Op op = OpConstraint.Op.None) : base(op)
{
}
public override ConstraintResult ApplyTo<TActual>(TActual actual)
{
IntPtr val;
bool success;
switch (actual)
{
case System.Runtime.InteropServices.SafeHandle h:
success = !h.IsInvalid;
val = h.DangerousGetHandle();
break;
case IHandle ih:
val = ih.DangerousGetHandle();
var l = val.ToInt64();
success = l != 0 && l != -1;
break;
case System.IntPtr p:
val = p;
l = val.ToInt64();
success = l != 0 && l != -1;
break;
default:
throw new InvalidCastException("Cannot get a handle from value.");
}
Description = $"Valid handle";
if (AppliedOp == Op.Not)
{
success = !success;
Description = $"Invalid handle";
}
return new ErrConstraintResult(this, string.Format("0x{0:X" + IntPtr.Size + "}", val.ToInt64()), success);
}
}
public class ValueConstraint : OpConstraint
{ {
public object Expected { get; } public object Expected { get; }
public ValueConstraint(object expected) public ValueConstraint(object expected, OpConstraint.Op op = OpConstraint.Op.None) : base(op)
{ {
Expected = expected; Expected = expected;
} }
public override ConstraintResult ApplyTo<TActual>(TActual actual) public override ConstraintResult ApplyTo<TActual>(TActual actual)
{ {
if (!(Expected?.Equals(actual) ?? actual == null)) var eq = new EqualConstraint(Expected);
{ Description = Prefix + eq.Description;
Description = $"{Expected}, {Win32Error.ERROR_SUCCESS}"; var success = eq.ApplyTo(actual).IsSuccess;
return new ConstraintResult(this, (actual, Win32Error.GetLastError()), false); if (AppliedOp == Op.Not)
} success = !success;
return new ConstraintResult(this, actual, true); return new ErrConstraintResult(this, actual, success);
} }
} }
public class ValidHandleConstraint : Constraint public class ErrConstraintResult : ConstraintResult
{ {
public ValidHandleConstraint() private readonly Win32Error lastErr;
public ErrConstraintResult(IConstraint constraint, object actualValue, bool isSuccessful) : base(constraint, actualValue, isSuccessful)
{ {
lastErr = Win32Error.GetLastError();
} }
public override ConstraintResult ApplyTo<TActual>(TActual actual) public override void WriteAdditionalLinesTo(MessageWriter writer) => writer.Write($" (Err: {lastErr})");
{
var success = true;
switch (actual)
{
case System.Runtime.InteropServices.SafeHandle h:
success = !h.IsInvalid;
break;
case IHandle ih:
var l = ih.DangerousGetHandle().ToInt64();
success = l != 0 && l != -1;
break;
case System.IntPtr p:
l = p.ToInt64();
success = l != 0 && l != -1;
break;
default:
break;
}
Description = $"Valid handle";
return new ConstraintResult(this, success ? "Valid handle" : $"Invalid handle (Err: {Win32Error.GetLastError()})", success);
}
} }
} }