Skip to content

Commit

Permalink
Add unit tests for parameters merging verification (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
michalkowal committed Aug 15, 2022
1 parent e505cca commit b5c466e
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ public class TranslatableCompositeData : SpecificationData<string>
public TranslatableCompositeData()
{
Valid("Custom mock message")
.Result(2, "TrueMockValidationSpecification[System.Object] Mock TrueMockValidationSpecification[System.Object]");
.Result(2, "MockCompositeInternalSpecification Mock MockCompositeInternalSpecification");

Invalid("Custom mock message")
.Result(2, "FailedFalseMockValidationSpecification[System.Object] Mock FailedFalseMockValidationSpecification[System.Object]", c =>
.Result(2, "FailedMockCompositeInternalSpecification Mock FailedMockCompositeInternalSpecification", c =>
{
c.CustomError("Custom mock message");
c.FailedSpecification(typeof(FalseMockValidationSpecification<object>),
c.FailedSpecification(typeof(FalseMockCompositeSpecification<object>.InternalSpecification),
"MockValidationSpecification is not satisfied")
.AddParameter("Result", false);
c.FailedSpecification(typeof(FalseMockValidationSpecification<object>),
.AddParameter("Result", false)
.AddParameter("External", 0);
c.FailedSpecification(typeof(FalseMockCompositeSpecification<object>.InternalSpecification),
"MockValidationSpecification is not satisfied")
.AddParameter("Result", false);
.AddParameter("Result", false)
.AddParameter("External", 0);
});
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
using FluentSpecification.Abstractions.Generic;
using FluentSpecification.Core.Composite;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace FluentSpecification.Core.Tests.Mocks
{
internal abstract class MockCompositeSpecification<T> : CompositeSpecification<T>
{
public class InternalSpecification : MockValidationSpecification<T>
{
private readonly int _externalParam;

public InternalSpecification(bool result, int externalParam) : base(result)
{
_externalParam = externalParam;
}

protected override string TraceMessage => "MockCompositeInternalSpecification";

protected override IReadOnlyDictionary<string, object> GetParameters()
{
var result = base.GetParameters().ToDictionary(kv => kv.Key, kv => kv.Value);
result.Add("External", _externalParam);

return result;
}
}

protected readonly bool Result;

protected MockCompositeSpecification(bool result)
: base(CreateBaseSpecification(result), CreateBaseSpecification(result), Expression.AndAlso)
protected MockCompositeSpecification(bool result, int leftParam, int rightParam)
: base(new InternalSpecification(result, leftParam), new InternalSpecification(result, rightParam), Expression.AndAlso)
{
Result = result;
}
Expand All @@ -21,74 +43,73 @@ protected override bool Merge(bool left, bool right)
return Result;
}

public static IComplexSpecification<T> Create(bool result)
{
return result ? True() : False();
}

public static IComplexSpecification<T> True()
public static IComplexSpecification<T> Create(bool result, int leftParam = 0, int rightParam = 0)
{
return new TrueMockCompositeSpecification<T>();
return result ? True(leftParam, rightParam) : False(leftParam, rightParam);
}

public static IComplexSpecification<T> False()
public static IComplexSpecification<T> True(int leftParam = 0, int rightParam = 0)
{
return new FalseMockCompositeSpecification<T>();
return new TrueMockCompositeSpecification<T>(leftParam, rightParam);
}

private static IValidationSpecification<T> CreateBaseSpecification(bool result)
public static IComplexSpecification<T> False(int leftParam = 0, int rightParam = 0)
{
return MockValidationSpecification<T>.Create(result);
return new FalseMockCompositeSpecification<T>(leftParam, rightParam);
}
}

internal class TrueMockCompositeSpecification<T> : MockCompositeSpecification<T>
{
public TrueMockCompositeSpecification() : base(true)
public TrueMockCompositeSpecification(int leftParam, int rightParam)
: base(true, leftParam, rightParam)
{
}
}

internal class FalseMockCompositeSpecification<T> : MockCompositeSpecification<T>
{
public FalseMockCompositeSpecification() : base(false)
public FalseMockCompositeSpecification(int leftParam, int rightParam)
: base(false, leftParam, rightParam)
{
}
}

internal abstract class MockCompositeSpecification : MockCompositeSpecification<object>
{
protected MockCompositeSpecification(bool result)
: base(result)
protected MockCompositeSpecification(bool result, int leftParam, int rightParam)
: base(result, leftParam, rightParam)
{
}

public new static IComplexSpecification<object> Create(bool result)
public new static IComplexSpecification<object> Create(bool result, int leftParam = 0, int rightParam = 0)
{
return result ? True() : False();
return result ? True(leftParam, rightParam) : False(leftParam, rightParam);
}

public new static IComplexSpecification<object> True()
public new static IComplexSpecification<object> True(int leftParam = 0, int rightParam = 0)
{
return new TrueMockCompositeSpecification();
return new TrueMockCompositeSpecification(leftParam, rightParam);
}

public new static IComplexSpecification<object> False()
public new static IComplexSpecification<object> False(int leftParam = 0, int rightParam = 0)
{
return new FalseMockCompositeSpecification();
return new FalseMockCompositeSpecification(leftParam, rightParam);
}
}

internal class TrueMockCompositeSpecification : MockCompositeSpecification
{
public TrueMockCompositeSpecification() : base(true)
public TrueMockCompositeSpecification(int leftParam, int rightParam)
: base(true, leftParam, rightParam)
{
}
}

internal class FalseMockCompositeSpecification : MockCompositeSpecification
{
public FalseMockCompositeSpecification() : base(false)
public FalseMockCompositeSpecification(int leftParam, int rightParam)
: base(false, leftParam, rightParam)
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public bool IsSatisfiedBy(T candidate, out SpecificationResult result)
return overall;
}

protected IReadOnlyDictionary<string, object> GetParameters()
protected virtual IReadOnlyDictionary<string, object> GetParameters()
{
return new Dictionary<string, object>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,55 @@ public void FalseCompositeSpecification_ReturnExpectedResultObject(string messag
Assert.Equal(expected, result, new SpecificationResultComparer(dum));
}

[Fact]
public void FalseCompositeSpecification_UniqueParametersInMessageFactory()
{
var candidate = new object();
var specification = MockCompositeSpecification.False(10, 10);

object expectedCandidate = null;
IReadOnlyDictionary<string, object> expectedParameters = null;
var sut = new TranslatableSpecification<object>(specification, (c, p) =>
{
expectedCandidate = c;
expectedParameters = p;
return string.Empty;
});

sut.IsSatisfiedBy(candidate, out var _);

Assert.Same(candidate, expectedCandidate);
Assert.NotNull(expectedParameters);
Assert.Equal(2, expectedParameters.Count);
Assert.IsType<int>(expectedParameters["External"]);
Assert.Equal(10, (int)expectedParameters["External"]);
}

[Fact]
public void FalseCompositeSpecification_ListWithMultipleParametersInMessageFactory()
{
var candidate = new object();
var specification = MockCompositeSpecification.False(1278, 145);

object expectedCandidate = null;
IReadOnlyDictionary<string, object> expectedParameters = null;
var sut = new TranslatableSpecification<object>(specification, (c, p) =>
{
expectedCandidate = c;
expectedParameters = p;
return string.Empty;
});

sut.IsSatisfiedBy(candidate, out var _);

Assert.Same(candidate, expectedCandidate);
Assert.NotNull(expectedParameters);
Assert.Equal(2, expectedParameters.Count);
Assert.IsType<object[]>(expectedParameters["External"]);
Assert.Equal(1278, ((object[])expectedParameters["External"])[0]);
Assert.Equal(145, ((object[])expectedParameters["External"])[1]);
}

[Theory]
[CorrectData(typeof(TranslatableData))]
public void NullCandidate_NoException(string message)
Expand Down

0 comments on commit b5c466e

Please sign in to comment.