< Summary

Information
Class: Orchestrator.Commands.Observability.EvaluationTimestampResolver
Assembly: Orchestrator
File(s): /home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Observability/EvaluationTimestampPolicy.cs
Line coverage
71%
Covered lines: 5
Uncovered lines: 2
Coverable lines: 7
Total lines: 98
Line coverage: 71.4%
Branch coverage
50%
Covered branches: 2
Total branches: 4
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Resolve(...)50%4471.43%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Observability/EvaluationTimestampPolicy.cs

#LineLine coverage
 1using EHonda.KicktippAi.Core;
 2using NodaTime;
 3using NodaTime.Text;
 4
 5namespace Orchestrator.Commands.Observability;
 6
 7internal sealed record EvaluationTimestampPolicy(
 8    string Kind,
 9    string Reference,
 10    Duration Offset)
 11{
 12    public const string RelativeKind = "relative";
 13    public const string StartsAtReference = "startsAt";
 14
 15    public static EvaluationTimestampPolicy CreateRelativeToMatchStart(Duration offset)
 16    {
 17        return new EvaluationTimestampPolicy(RelativeKind, StartsAtReference, offset);
 18    }
 19}
 20
 21internal static class EvaluationTimestampPolicyParser
 22{
 23    private static readonly DurationPattern[] SupportedDurationPatterns =
 24    [
 25        DurationPattern.JsonRoundtrip,
 26        DurationPattern.Roundtrip
 27    ];
 28
 29    public static EvaluationTimestampPolicy? ParseOrNull(string? kind, string? offset)
 30    {
 31        if (string.IsNullOrWhiteSpace(kind) && string.IsNullOrWhiteSpace(offset))
 32        {
 33            return null;
 34        }
 35
 36        return Parse(kind, offset);
 37    }
 38
 39    public static EvaluationTimestampPolicy Parse(string? kind, string? offset)
 40    {
 41        kind = Normalize(kind, nameof(kind));
 42        offset = Normalize(offset, nameof(offset));
 43
 44        if (!string.Equals(kind, EvaluationTimestampPolicy.RelativeKind, StringComparison.OrdinalIgnoreCase))
 45        {
 46            throw new ArgumentException(
 47                $"Evaluation policy kind must currently be '{EvaluationTimestampPolicy.RelativeKind}'.",
 48                nameof(kind));
 49        }
 50
 51        foreach (var pattern in SupportedDurationPatterns)
 52        {
 53            var parseResult = pattern.Parse(offset);
 54            if (parseResult.Success)
 55            {
 56                return EvaluationTimestampPolicy.CreateRelativeToMatchStart(parseResult.Value);
 57            }
 58        }
 59
 60        throw new ArgumentException(
 61            "Evaluation policy offset must use a supported NodaTime Duration format, for example '-12:00:00' or '-0:12:0
 62            nameof(offset));
 63    }
 64
 65    private static string Normalize(string? value, string parameterName)
 66    {
 67        ArgumentException.ThrowIfNullOrWhiteSpace(value, parameterName);
 68
 69        value = value.Trim();
 70        if (value.Length >= 2 && value[0] == '"' && value[^1] == '"')
 71        {
 72            value = value[1..^1];
 73        }
 74
 75        return value;
 76    }
 77}
 78
 79internal static class EvaluationTimestampResolver
 80{
 81    public static DateTimeOffset Resolve(Match match, EvaluationTimestampPolicy policy)
 82    {
 183        ArgumentNullException.ThrowIfNull(match);
 184        ArgumentNullException.ThrowIfNull(policy);
 85
 186        if (!string.Equals(policy.Kind, EvaluationTimestampPolicy.RelativeKind, StringComparison.Ordinal))
 87        {
 088            throw new ArgumentException($"Unsupported evaluation policy kind '{policy.Kind}'.", nameof(policy));
 89        }
 90
 191        if (!string.Equals(policy.Reference, EvaluationTimestampPolicy.StartsAtReference, StringComparison.Ordinal))
 92        {
 093            throw new ArgumentException($"Unsupported evaluation policy reference '{policy.Reference}'.", nameof(policy)
 94        }
 95
 196        return (match.StartsAt + policy.Offset).ToDateTimeOffset();
 97    }
 98}