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

ImmediatePlatform / Immediate.Jobs / 30304771671

27 Jul 2026 08:56PM UTC coverage: 65.995%. First build
30304771671

Pull #33

github

web-flow
Merge 46c3047f1 into e9a147742
Pull Request #33: Improve Storage API

1521 of 2481 new or added lines in 28 files covered. (61.31%)

4326 of 6555 relevant lines covered (66.0%)

2.22 hits per line

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

64.29
/src/Immediate.Jobs.Testing/CaptureOnlyJobScheduler.cs
1
namespace Immediate.Jobs.Testing;
2

3
/// <summary>
4
/// A storage-free implementation of <see cref="IJobScheduler{TPayload}"/> that records scheduled calls.
5
/// </summary>
6
public class CaptureOnlyJobScheduler<TPayload>(TimeProvider? timeProvider = null) : IJobScheduler<TPayload>
4✔
7
{
8
        private readonly List<ScheduledJobCapture<TPayload>> _captures = [];
4✔
9
        private readonly TimeProvider _timeProvider = timeProvider ?? TimeProvider.System;
4✔
10

11
        /// <summary>All calls captured in call order.</summary>
12
        public IReadOnlyList<ScheduledJobCapture<TPayload>> Captures => _captures;
4✔
13

14
        /// <summary>The latest captured call, or <see langword="null"/> when none exists.</summary>
15
        public ScheduledJobCapture<TPayload>? Last => _captures.Count == 0 ? null : _captures[^1];
×
16

17
        /// <inheritdoc />
18
        public virtual ValueTask<JobHandle> EnqueueAsync(TPayload payload, CancellationToken cancellationToken = default) =>
NEW
19
                CaptureAsync(payload, _timeProvider.GetUtcNow(), groupId: null, cancellationToken);
×
20

21
        /// <inheritdoc />
22
        public virtual ValueTask<JobHandle> EnqueueAsync(
23
                TPayload payload,
24
                string? groupId,
25
                CancellationToken cancellationToken = default
26
        ) => CaptureAsync(payload, _timeProvider.GetUtcNow(), groupId, cancellationToken);
4✔
27

28
        /// <inheritdoc />
29
        public virtual ValueTask<JobHandle> ScheduleAsync(
30
                TPayload payload,
31
                TimeSpan delay,
32
                CancellationToken cancellationToken = default
33
        )
34
        {
NEW
35
                if (delay < TimeSpan.Zero)
×
NEW
36
                        throw new ArgumentOutOfRangeException(nameof(delay), "A job delay cannot be negative.");
×
NEW
37
                return CaptureAsync(payload, _timeProvider.GetUtcNow() + delay, groupId: null, cancellationToken);
×
38
        }
39

40
        /// <inheritdoc />
41
        public virtual ValueTask<JobHandle> ScheduleAsync(
42
                TPayload payload,
43
                TimeSpan delay,
44
                string? groupId,
45
                CancellationToken cancellationToken = default
46
        )
47
        {
48
                if (delay < TimeSpan.Zero)
4✔
49
                        throw new ArgumentOutOfRangeException(nameof(delay), "A job delay cannot be negative.");
×
50
                return CaptureAsync(payload, _timeProvider.GetUtcNow() + delay, groupId, cancellationToken);
4✔
51
        }
52

53
        /// <inheritdoc />
54
        public virtual ValueTask<JobHandle> ScheduleAtAsync(
55
                TPayload payload,
56
                DateTimeOffset runAt,
57
                CancellationToken cancellationToken = default
NEW
58
        ) => CaptureAsync(payload, runAt, groupId: null, cancellationToken);
×
59

60
        /// <inheritdoc />
61
        public virtual ValueTask<JobHandle> ScheduleAtAsync(
62
                TPayload payload,
63
                DateTimeOffset runAt,
64
                string? groupId,
65
                CancellationToken cancellationToken = default
66
        ) => CaptureAsync(payload, runAt, groupId, cancellationToken);
4✔
67

68
        /// <summary>Clears every captured call.</summary>
69
        public void Clear() => _captures.Clear();
×
70

71
        /// <summary>Creates invocation identifiers. Override when a test requires predictable identifiers.</summary>
72
        protected virtual string CreateId() => Guid.NewGuid().ToString("N");
4✔
73

74
        private ValueTask<JobHandle> CaptureAsync(
75
                TPayload payload,
76
                DateTimeOffset runAt,
77
                string? groupId,
78
                CancellationToken cancellationToken
79
        )
80
        {
81
                cancellationToken.ThrowIfCancellationRequested();
4✔
82
                groupId = NormalizeGroupId(groupId);
4✔
83
                var id = CreateId();
4✔
84
                _captures.Add(new(id, payload, runAt) { GroupId = groupId });
4✔
85
                return ValueTask.FromResult(new JobHandle(id));
4✔
86
        }
87

88
        private static string? NormalizeGroupId(string? groupId)
89
        {
90
                if (string.IsNullOrWhiteSpace(groupId))
4✔
NEW
91
                        return null;
×
92
                if (groupId.Length > 128)
4✔
NEW
93
                        throw new ArgumentException("A fair queue group id cannot exceed 128 characters.", nameof(groupId));
×
94
                return groupId;
4✔
95
        }
96
}
97

98
/// <summary>A captured typed scheduler call.</summary>
99
public sealed record ScheduledJobCapture<TPayload>(string Id, TPayload Payload, DateTimeOffset RunAt)
4✔
100
{
101
        /// <summary>The normalized fair queue group id supplied to the scheduler.</summary>
102
        public string? GroupId { get; init; }
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc