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

lucaslorentz / auto-compute / 18778187096

24 Oct 2025 11:14AM UTC coverage: 83.295% (-0.2%) from 83.516%
18778187096

push

github

lucaslorentz
Move IncrementalContext param into Input param

56 of 58 new or added lines in 22 files covered. (96.55%)

8 existing lines in 5 files now uncovered.

1790 of 2149 relevant lines covered (83.29%)

880.64 hits per line

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

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

4
namespace LLL.AutoCompute.ChangesProviders;
5

6
public class ComputedChangesProvider<TInput, TEntity, TValue, TChange>(
224✔
7
    Expression<Func<TEntity, TValue>> expression,
224✔
8
    EntityContext entityContext,
224✔
9
    Func<TEntity, bool> filter,
224✔
10
    EntityContext filterEntityContext,
224✔
11
    IChangeCalculator<TValue, TChange> changeCalculation,
224✔
12
    Func<TInput, TEntity, TValue> originalValueGetter,
224✔
13
    Func<TInput, TEntity, TValue> currentValueGetter
224✔
14
) : IComputedChangesProvider<TInput, TEntity, TChange>
224✔
15
    where TEntity : class
16
    where TInput : ComputedInput
17
{
18
    LambdaExpression IComputedChangesProvider.Expression => expression;
158✔
UNCOV
19
    public Expression<Func<TEntity, TValue>> Expression => expression;
×
20
    public EntityContext EntityContext => entityContext;
80✔
21
    public IReadOnlySet<IObservedMember> ObservedMembers { get; } = entityContext.GetAllObservedMembers().ToHashSet();
716✔
22
    public IChangeCalculator<TChange> ChangeCalculation => changeCalculation;
2,516✔
23

24
    public async Task<IReadOnlyDictionary<TEntity, TChange>> GetChangesAsync(
25
        TInput input,
26
        ChangeMemory<TEntity, TChange>? changeMemory)
27
    {
28
        input.IncrementalContext = changeCalculation.IsIncremental
2,144✔
29
            ? new IncrementalContext()
2,144✔
30
            : null;
2,144✔
31

32
        var affectedEntities = (await entityContext.GetAffectedEntitiesAsync(input))
2,144✔
33
            .OfType<TEntity>()
2,144✔
34
            .ToArray();
2,144✔
35

36
        await filterEntityContext.PreLoadNavigationsAsync(input!, affectedEntities);
2,144✔
37

38
        affectedEntities = affectedEntities
2,144✔
39
            .Where(e => entityContext.EntityType.GetEntityState(input!, e) != ObservedEntityState.Removed
4,786✔
40
                && filter(e))
4,786✔
41
            .ToArray();
2,144✔
42

43
        if (input.IncrementalContext is not null)
2,144✔
44
            await entityContext.EnrichIncrementalContextAsync(input!, affectedEntities);
184✔
45
        else if (changeCalculation.PreLoadEntities)
1,960✔
46
            await entityContext.PreLoadNavigationsAsync(input!, affectedEntities);
1,956✔
47

48
        var changes = new Dictionary<TEntity, TChange>();
2,144✔
49

50
        foreach (var entity in affectedEntities)
9,568✔
51
        {
52
            changes[entity] = await GetChangeAsync(input, entity, changeMemory);
2,640✔
53
        }
54

55
        if (changeMemory is not null)
2,144✔
56
        {
57
            foreach (var entity in changeMemory.GetEntities())
668✔
58
            {
59
                if (changes.ContainsKey(entity))
162✔
60
                    continue;
61

62
                changes[entity] = await GetChangeAsync(input, entity, changeMemory);
2✔
63
                changeMemory.Remove(entity);
2✔
64
            }
65
        }
66

67
        var filteredChanges = changes
2,144✔
68
            .Where(kv => !changeCalculation.IsNoChange(kv.Value));
4,786✔
69

70
        return new Dictionary<TEntity, TChange>(filteredChanges);
2,144✔
71
    }
72

73
    private async Task<TChange> GetChangeAsync(
74
        TInput input,
75
        TEntity entity,
76
        ChangeMemory<TEntity, TChange>? changeMemory)
77
    {
78
        var valueChange = changeCalculation.GetChange(CreateComputedValues(input, entity));
2,642✔
79
        return DeltaChange(changeMemory, entity, valueChange);
2,642✔
80
    }
81

82
    private TChange DeltaChange(ChangeMemory<TEntity, TChange>? changeMemory, TEntity entity, TChange result)
83
    {
84
        if (changeMemory is null)
2,642✔
85
            return result;
2,480✔
86

87
        var delta = changeMemory.TryGet(entity, out var previousResult)
162✔
88
            ? ChangeCalculation.DeltaChange(previousResult, result)
162✔
89
            : result;
162✔
90

91
        changeMemory.AddOrUpdate(entity, result);
162✔
92

93
        return delta;
162✔
94
    }
95

96
    private ComputedValues<TInput, TEntity, TValue> CreateComputedValues(TInput input, TEntity entity)
97
    {
98
        return new ComputedValues<TInput, TEntity, TValue>(
2,642✔
99
            input,
2,642✔
100
            entity,
2,642✔
101
            originalValueGetter,
2,642✔
102
            currentValueGetter);
2,642✔
103
    }
104
}
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