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

moconnell / yolo / 28953756537

08 Jul 2026 03:15PM UTC coverage: 86.808% (+3.9%) from 82.93%
28953756537

push

github

web-flow
Feat: Telemetry  (#131)

* feat(telemetry): record web service JSON, trade execution data

* feat(telemetry): add query endpoints

* fix(RebalanceCommand): handle TradeExecutionRecorder exception

* fix(RawJsonPersistenceHandler): update BuildContentHash per review recommendation

* fix: review snags

* test: azure storage queries

* fix(StorageQueryFunctionsTest): review snag

* test: improve coverage

* feat(telemetry): add rebalance event log

* fix(AzureTableRebalanceEventRecorder): remove table init from hot path

* delete: trade execution telemetry

* fix(StorageQueryFunctions): ensure filter correctness

* feat(effective-weights): add BufferAdjustedTargetWeight at the coin level

* feat(telemetry): store new FactorsCalculated event

* feat(effective-weights): add IsTestnet to response

* fix: tests

* feat(HttpQueryParameters): handle more from/to filter date formats

413 of 449 branches covered (91.98%)

Branch coverage included in aggregate %.

789 of 898 new or added lines in 18 files covered. (87.86%)

3 existing lines in 1 file now uncovered.

3522 of 4084 relevant lines covered (86.24%)

24.18 hits per line

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

98.73
/src/YoloFunk/Infrastructure/HttpQueryParameters.cs
1
using System.Globalization;
2

3
namespace YoloFunk.Infrastructure;
4

5
internal sealed class HttpQueryParameters
6
{
7
    private readonly Dictionary<string, string[]> _values;
8

9
    private HttpQueryParameters(Dictionary<string, string[]> values)
7✔
10
    {
7✔
11
        _values = values;
7✔
12
    }
7✔
13

14
    public static HttpQueryParameters Parse(Uri url)
15
    {
7✔
16
        var values = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
7✔
17
        var query = url.Query.TrimStart('?');
7✔
18
        foreach (var pair in query.Split('&', StringSplitOptions.RemoveEmptyEntries))
51✔
19
        {
15✔
20
            var parts = pair.Split('=', 2);
15✔
21
            var key = Uri.UnescapeDataString(parts[0].Replace("+", " "));
15✔
22
            if (string.IsNullOrWhiteSpace(key))
15✔
NEW
23
                continue;
×
24

25
            var value = parts.Length > 1
15✔
26
                ? Uri.UnescapeDataString(parts[1].Replace("+", " "))
15✔
27
                : string.Empty;
15✔
28

29
            if (!values.TryGetValue(key, out var list))
15✔
30
            {
15✔
31
                list = [];
15✔
32
                values[key] = list;
15✔
33
            }
15✔
34

35
            list.Add(value);
15✔
36
        }
15✔
37

38
        return new HttpQueryParameters(
7✔
39
            values.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray(), StringComparer.OrdinalIgnoreCase));
37✔
40
    }
7✔
41

42
    public string? GetString(string name)
43
    {
77✔
44
        return _values.TryGetValue(name, out var values)
77✔
45
            ? values.FirstOrDefault(value => !string.IsNullOrWhiteSpace(value))
15✔
46
            : null;
77✔
47
    }
77✔
48

49
    public int GetInt32(string name, int defaultValue, int min, int max)
50
    {
12✔
51
        var value = GetString(name);
12✔
52
        if (!int.TryParse(value, out var parsed))
12✔
53
            return defaultValue;
10✔
54

55
        return Math.Clamp(parsed, min, max);
2✔
56
    }
12✔
57

58
    public DateTimeOffset? GetDateTimeOffset(string name)
59
    {
12✔
60
        var value = GetString(name);
12✔
61
        if (string.IsNullOrWhiteSpace(value))
12✔
62
            return null;
8✔
63

64
        if (DateOnly.TryParseExact(
4✔
65
                value,
4✔
66
                "yyyy-MM-dd",
4✔
67
                CultureInfo.InvariantCulture,
4✔
68
                DateTimeStyles.None,
4✔
69
                out var date))
4✔
70
        {
2✔
71
            var dateTime = string.Equals(name, "to", StringComparison.OrdinalIgnoreCase)
2✔
72
                ? date.ToDateTime(TimeOnly.MaxValue)
2✔
73
                : date.ToDateTime(TimeOnly.MinValue);
2✔
74
            return new DateTimeOffset(dateTime, TimeSpan.Zero);
2✔
75
        }
76

77
        string[] formats =
2✔
78
        [
2✔
79
            "O",
2✔
80
            "yyyy-MM-dd'T'HH:mm:ss.FFFFFFFK",
2✔
81
            "yyyy-MM-dd'T'HH:mm:ssK",
2✔
82
            "yyyy-MM-dd'T'HH:mm:ss.FFFFFFFzzz",
2✔
83
            "yyyy-MM-dd'T'HH:mm:sszzz"
2✔
84
        ];
2✔
85

86
        return DateTimeOffset.TryParseExact(
2✔
87
            value,
2✔
88
            formats,
2✔
89
            CultureInfo.InvariantCulture,
2✔
90
            DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal,
2✔
91
            out var parsed)
2✔
92
            ? parsed
2✔
93
            : null;
2✔
94
    }
12✔
95
}
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