• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lucaslorentz / auto-compute / 11755625072

09 Nov 2024 10:48AM UTC coverage: 79.945% (-0.09%) from 80.033%
11755625072

push

github

lucaslorentz
Add initial support for computed navigations and observers

159 of 359 new or added lines in 22 files covered. (44.29%)

41 existing lines in 7 files now uncovered.

1459 of 1825 relevant lines covered (79.95%)

113.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.23
/src/LLL.AutoCompute/ChangesProviders/UnboundChangesProvider.cs
1
using System.Linq.Expressions;
2
using LLL.AutoCompute.EntityContexts;
3

4
namespace LLL.AutoCompute.ChangesProviders;
5

6
public class UnboundChangesProvider<TInput, TEntity, TValue, TChange>(
30✔
7
    Expression<Func<TEntity, TValue>> expression,
30✔
8
    EntityContext entityContext,
30✔
9
    Func<TEntity, bool> filter,
30✔
10
    EntityContext filterEntityContext,
30✔
11
    IEntityActionProvider entityActionProvider,
30✔
12
    IChangeCalculation<TValue, TChange> changeCalculation,
30✔
13
    ComputedValueAccessors<TInput, TEntity, TValue> computedValueAccessors
30✔
14
) : IUnboundChangesProvider<TInput, TEntity, TChange>
30✔
15
    where TEntity : class
16
{
NEW
17
    LambdaExpression IUnboundChangesProvider.Expression => expression;
×
NEW
18
    public Expression<Func<TEntity, TValue>> Expression => expression;
×
19
    public EntityContext EntityContext => entityContext;
25✔
20
    public IChangeCalculation<TChange> ChangeCalculation => changeCalculation;
112✔
21

22
    public async Task<IReadOnlyDictionary<TEntity, TChange>> GetChangesAsync(
23
        TInput input,
24
        ChangeMemory<TEntity, TChange>? changeMemory)
25
    {
26
        var incrementalContext = new IncrementalContext();
155✔
27

28
        var affectedEntities = (await entityContext.GetAffectedEntitiesAsync(input!, incrementalContext))
155✔
29
            .Cast<TEntity>()
155✔
30
            .ToArray();
155✔
31

32
        await filterEntityContext.PreLoadNavigationsAsync(input!, affectedEntities, incrementalContext);
155✔
33

34
        affectedEntities = affectedEntities
155✔
35
            .Where(e => entityActionProvider.GetEntityAction(input!, e) != EntityAction.Delete
334✔
36
                && filter(e))
334✔
37
            .ToArray();
155✔
38

39
        if (changeCalculation.IsIncremental)
155✔
40
            await entityContext.EnrichIncrementalContextAsync(input!, affectedEntities, incrementalContext);
61✔
41
        else if (changeCalculation.PreLoadEntities)
94✔
42
            await entityContext.PreLoadNavigationsAsync(input!, affectedEntities, incrementalContext);
84✔
43

44
        var changes = new Dictionary<TEntity, TChange>();
155✔
45

46
        foreach (var entity in affectedEntities)
666✔
47
        {
48
            changes[entity] = await GetChangeAsync(input, entity, incrementalContext, changeMemory);
178✔
49
        }
50

51
        if (changeMemory is not null)
155✔
52
        {
53
            foreach (var entity in changeMemory.GetEntities())
338✔
54
            {
55
                if (changes.ContainsKey(entity))
84✔
56
                    continue;
57

58
                changes[entity] = await GetChangeAsync(input, entity, incrementalContext, changeMemory);
2✔
59
                changeMemory.Remove(entity);
2✔
60
            }
61
        }
62

63
        var filteredChanges = changes
155✔
64
            .Where(kv => !changeCalculation.IsNoChange(kv.Value));
335✔
65

66
        return new Dictionary<TEntity, TChange>(filteredChanges);
155✔
67
    }
68

69
    private async Task<TChange> GetChangeAsync(
70
        TInput input,
71
        TEntity entity,
72
        IncrementalContext incrementalContext,
73
        ChangeMemory<TEntity, TChange>? changeMemory)
74
    {
75
        var valueChange = changeCalculation.GetChange(CreateComputedValues(input, entity, incrementalContext));
180✔
76
        return DeltaChange(changeMemory, entity, valueChange);
180✔
77
    }
78

79
    private TChange DeltaChange(ChangeMemory<TEntity, TChange>? changeMemory, TEntity entity, TChange result)
80
    {
81
        if (changeMemory is null)
180✔
82
            return result;
96✔
83

84
        var delta = changeMemory.TryGet(entity, out var previousResult)
84✔
85
            ? ChangeCalculation.DeltaChange(previousResult, result)
84✔
86
            : result;
84✔
87

88
        changeMemory.AddOrUpdate(entity, result);
84✔
89

90
        return delta;
84✔
91
    }
92

93
    private ComputedValues<TInput, TEntity, TValue> CreateComputedValues(TInput input, TEntity entity, IncrementalContext incrementalContext)
94
    {
95
        return new ComputedValues<TInput, TEntity, TValue>(
180✔
96
            input,
180✔
97
            incrementalContext,
180✔
98
            entity,
180✔
99
            computedValueAccessors);
180✔
100
    }
101

UNCOV
102
    public record class ValueWrapper(TChange Value);
×
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc