Skip to content

Commit 5753a56

Browse files
committed
- Add unit tests for hooks
1 parent 88cd3e8 commit 5753a56

File tree

5 files changed

+101
-16
lines changed

5 files changed

+101
-16
lines changed

src/Schemio.Core/Impl/EntityBuilder.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public T Build(IDataContext context, IList<IQueryResult> queryResults)
4444

4545
foreach (var queryResult in queryResults)
4646
transformers.Where(transformer => IsMatch(((ITransformerQueryResult)transformer).SupportedQueryResult, queryResult.GetType())).ToList()
47-
.ForEach(transformer => TransformWithHooks(new TransformContext(context, queryResult, transformer, entity)));
47+
.ForEach(transformer => TransformWithHooks(new TransformContext(context, queryResult, transformer, entity, false)));
4848
}
4949

5050
return entity;
@@ -78,15 +78,20 @@ private void TransformWithHooks(TransformContext context)
7878
context.Transformer.Transform(context.QueryResult, context.Entity);
7979

8080
// Post-transform hook can be used to perform any post-transformation logic if needed.
81-
if (context.Transformer is ITransformerHooks transformerPostHook)
81+
if (!preTransformContext.IsCancelled && context.Transformer is ITransformerHooks transformerPostHook)
8282
{
8383
// Create a post-transform context to pass the data after transformation.
8484
var postTransformContext = new PostTransformContext(context);
8585
// Call the post-transform method with the context.
8686
transformerPostHook.PostTransform(postTransformContext);
8787
// If the post-transform context is repeat, transform again.
88-
if (postTransformContext.IsRepeat)
89-
context.Transformer.Transform(context.QueryResult, context.Entity);
88+
if (!postTransformContext.IsRepeated && postTransformContext.IsRepeat)
89+
{
90+
// Mark as repeated to avoid infinite loop.
91+
postTransformContext.IsRepeated = true;
92+
// Repeat the transformation process.
93+
TransformWithHooks(postTransformContext);
94+
}
9095
}
9196
}
9297
}

src/Schemio.Core/PostTransformContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class PostTransformContext : TransformContext
2020
/// </summary>
2121
/// <param name="context">TransformContext</param>
2222
public PostTransformContext(TransformContext context) :
23-
base(context.DataContext, context.QueryResult, context.Transformer, context.Entity)
23+
base(context.DataContext, context.QueryResult, context.Transformer, context.Entity, context.IsRepeated)
2424
{
2525
}
2626
}

src/Schemio.Core/PreTransformContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class PreTransformContext : TransformContext
1717
/// </summary>
1818
/// <param name="context">TransformContext</param>
1919
public PreTransformContext(TransformContext context) :
20-
base(context.DataContext, context.QueryResult, context.Transformer, context.Entity)
20+
base(context.DataContext, context.QueryResult, context.Transformer, context.Entity, context.IsRepeated)
2121
{
2222
}
2323
}

src/Schemio.Core/TransformContext.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,25 @@ public Type TransformerType
2727
/// </summary>
2828
public IQueryResult QueryResult { get; private set; }
2929

30+
/// <summary>
31+
/// Indicates whether the transformation has been repeated.
32+
/// </summary>
33+
internal bool IsRepeated { get; set; }
34+
3035
/// <summary>
3136
/// Creates a new instance of TransformContext with the provided parameters.
3237
/// </summary>
3338
/// <param name="dataContext"></param>
3439
/// <param name="queryResult"></param>
3540
/// <param name="transformerType"></param>
3641
/// <param name="entity"></param>
37-
public TransformContext(IDataContext dataContext, IQueryResult queryResult, ITransformer transformer, IEntity entity)
42+
public TransformContext(IDataContext dataContext, IQueryResult queryResult, ITransformer transformer, IEntity entity, bool isRepeated)
3843
{
3944
DataContext = dataContext;
4045
QueryResult = queryResult;
4146
Transformer = transformer;
4247
Entity = entity;
48+
IsRepeated = isRepeated;
4349
}
4450
}
4551
}

tests/Schemio.Core.Tests/DataProvider.Tests/EntityBuilderTests.cs

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,30 @@ internal class EntityBuilderTests
1010
private EntityBuilder<Customer> _entityBuilder;
1111
private IEntityConfiguration<Customer> _entitySchema;
1212

13-
private static List<(Type result, int InvocationCount)> TransformerInvocations;
13+
public class Invocations
14+
{
15+
public Invocations(Type result, int invocationCount, int preInvocationCount, int postInvocationCount)
16+
{
17+
Result = result;
18+
InvocationCount = invocationCount;
19+
PreInvocationCount = preInvocationCount;
20+
PostInvocationCount = postInvocationCount;
21+
}
22+
23+
public Type Result { get; set; }
24+
public int InvocationCount { get; set; }
25+
public int PreInvocationCount { get; set; }
26+
public int PostInvocationCount { get; set; }
27+
}
28+
29+
private static List<Invocations> TransformerInvocations;
1430

1531
[SetUp]
1632
public void Setup()
1733
{
1834
_entitySchema = new MockCustomerSchema();
1935
_entityBuilder = new EntityBuilder<Customer>(_entitySchema);
20-
TransformerInvocations = new List<(Type result, int InvocationCount)>();
36+
TransformerInvocations = new List<Invocations>();
2137
}
2238

2339
[Test]
@@ -33,21 +49,31 @@ public void TestTransformExecutorForCorrectExecutionOfConfiguredTransforms()
3349

3450
var entity = _entityBuilder.Build(new DataContext(new EntityContext()), queryList);
3551

36-
var customerTransforms = TransformerInvocations.Where(x => x.result == typeof(CustomerRecord));
52+
var customerTransforms = TransformerInvocations.Where(x => x.Result == typeof(CustomerRecord));
3753
Assert.That(customerTransforms.Count() == 1);
54+
Assert.That(customerTransforms.ElementAt(0).PreInvocationCount == 1);
3855
Assert.That(customerTransforms.ElementAt(0).InvocationCount == 1);
56+
Assert.That(customerTransforms.ElementAt(0).PostInvocationCount == 1);
3957

40-
var communicationTransforms = TransformerInvocations.Where(x => x.result == typeof(CommunicationRecord));
58+
// Assert that the communication transform is invoked twice due to the repeat in PostTransform
59+
var communicationTransforms = TransformerInvocations.Where(x => x.Result == typeof(CommunicationRecord));
4160
Assert.That(communicationTransforms.Count() == 1);
42-
Assert.That(communicationTransforms.ElementAt(0).InvocationCount == 1);
61+
Assert.That(communicationTransforms.ElementAt(0).PreInvocationCount == 2);
62+
Assert.That(communicationTransforms.ElementAt(0).InvocationCount == 2);
63+
Assert.That(communicationTransforms.ElementAt(0).PostInvocationCount == 2);
4364

44-
var orderCollectionTransforms = TransformerInvocations.Where(x => x.result == typeof(CollectionResult<OrderRecord>));
65+
var orderCollectionTransforms = TransformerInvocations.Where(x => x.Result == typeof(CollectionResult<OrderRecord>));
4566
Assert.That(orderCollectionTransforms.Count() == 1);
67+
Assert.That(orderCollectionTransforms.ElementAt(0).PreInvocationCount == 1);
4668
Assert.That(orderCollectionTransforms.ElementAt(0).InvocationCount == 1);
69+
Assert.That(orderCollectionTransforms.ElementAt(0).PostInvocationCount == 1);
4770

48-
var orderItemsCollectionTransforms = TransformerInvocations.Where(x => x.result == typeof(CollectionResult<OrderItemRecord>));
71+
// Assert that the order items transform is not invoked due to cancellation in PreTransform
72+
var orderItemsCollectionTransforms = TransformerInvocations.Where(x => x.Result == typeof(CollectionResult<OrderItemRecord>));
4973
Assert.That(orderItemsCollectionTransforms.Count() == 1);
50-
Assert.That(orderItemsCollectionTransforms.ElementAt(0).InvocationCount == 1);
74+
Assert.That(orderItemsCollectionTransforms.ElementAt(0).PreInvocationCount == 1);
75+
Assert.That(orderItemsCollectionTransforms.ElementAt(0).InvocationCount == 0);
76+
Assert.That(orderItemsCollectionTransforms.ElementAt(0).PostInvocationCount == 0);
5177

5278
Assert.That(entity, Is.Not.Null);
5379
}
@@ -58,7 +84,55 @@ public class MockTransform<TQueryResult, TEntity> : BaseTransformer<TQueryResult
5884
{
5985
public override void Transform(TQueryResult queryResult, TEntity entity)
6086
{
61-
TransformerInvocations.Add((queryResult.GetType(), 1));
87+
var invocations = TransformerInvocations.Where(x => x.Result == queryResult.GetType());
88+
89+
if (!invocations.Any())
90+
return;
91+
92+
var transformInvocations = invocations
93+
.Select(x => new Invocations(x.Result, x.InvocationCount + 1, x.PreInvocationCount, x.PostInvocationCount)).ToList();
94+
95+
TransformerInvocations.RemoveAll(x => x.Result == queryResult.GetType());
96+
TransformerInvocations.AddRange(transformInvocations);
97+
}
98+
99+
public override void PreTransform(PreTransformContext context)
100+
{
101+
var invocation = TransformerInvocations.FirstOrDefault(x => x.Result == context.QueryResult.GetType());
102+
103+
if (invocation != null)
104+
{
105+
TransformerInvocations.Remove(invocation);
106+
TransformerInvocations.Add(new Invocations(invocation.Result, invocation.InvocationCount, invocation.PreInvocationCount + 1, invocation.PostInvocationCount));
107+
}
108+
else
109+
{
110+
TransformerInvocations.Add(new Invocations(context.QueryResult.GetType(), 0, 1, 0));
111+
}
112+
113+
if (context.QueryResult is CollectionResult<OrderItemRecord> orderItems)
114+
{
115+
context.Cancel();
116+
}
117+
}
118+
119+
public override void PostTransform(PostTransformContext context)
120+
{
121+
var invocations = TransformerInvocations.Where(x => x.Result == context.QueryResult.GetType());
122+
123+
if (!invocations.Any())
124+
return;
125+
126+
var transformInvocations = invocations
127+
.Select(x => new Invocations(x.Result, x.InvocationCount, x.PreInvocationCount, x.PostInvocationCount + 1)).ToList();
128+
129+
TransformerInvocations.RemoveAll(x => x.Result == context.QueryResult.GetType());
130+
TransformerInvocations.AddRange(transformInvocations);
131+
132+
if (context.QueryResult is CommunicationRecord communication)
133+
{
134+
context.Repeat();
135+
}
62136
}
63137
}
64138

0 commit comments

Comments
 (0)