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

orion-ecs / keen-eye / 20386896415

20 Dec 2025 01:18AM UTC coverage: 62.508% (-24.5%) from 87.015%
20386896415

push

github

tyevco
Add KeenEyes.Testing Phase 2: Graphics, Platform, Logging, Encryption, Network mocks

Implements comprehensive testing infrastructure for headless game testing:

Graphics mocks:
- MockWindow: Headless window with lifecycle events and device creation
- MockGraphicsDevice: Low-level GPU state tracking (buffers, textures, shaders)
- MockGraphicsContext: High-level GPU operations with resource management
- Mock2DRenderer: 2D rendering command recording with batching
- MockTextRenderer: Text rendering with effects (outline, shadow)
- MockFontManager: Font metrics and text measurement
- GraphicsAssertions: Fluent verification helpers

Platform mocks:
- MockLoopProvider: Step-through game loop for deterministic testing
- LoopAssertions: Loop behavior verification

Logging mocks:
- MockLogProvider: Log capture with level filtering
- LogAssertions: Log verification (errors, warnings, content matching)

Encryption mocks:
- MockEncryptionProvider: PassThrough, Reversible, and Tracking modes
- EncryptionAssertions: Encryption operation verification

Network mocks:
- INetworkContext: Network abstraction interface
- MockNetworkContext: Connection simulation, message queuing, latency/packet loss
- NetworkConnectionState: Connection state enumeration

Also includes:
- Input mocks from Phase 1 (MockInputContext, MockKeyboard, MockMouse, MockGamepad)
- Event recording and assertions
- Plugin testing infrastructure
- TestWorld and TestWorldBuilder integration

Tests: 460 passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

2695 of 3764 branches covered (71.6%)

Branch coverage included in aggregate %.

1238 of 2566 new or added lines in 29 files covered. (48.25%)

172 existing lines in 6 files now uncovered.

15461 of 25282 relevant lines covered (61.15%)

0.85 hits per line

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

0.0
/src/KeenEyes.Testing/Encryption/EncryptionAssertions.cs
1
namespace KeenEyes.Testing.Encryption;
2

3
/// <summary>
4
/// Fluent assertions for encryption verification.
5
/// </summary>
6
public static class EncryptionAssertions
7
{
8
    /// <summary>
9
    /// Asserts that encryption was called at least once.
10
    /// </summary>
11
    /// <param name="provider">The mock encryption provider.</param>
12
    /// <returns>The provider for chaining.</returns>
13
    /// <exception cref="AssertionException">Thrown when no encryption occurred.</exception>
14
    public static MockEncryptionProvider ShouldHaveEncrypted(this MockEncryptionProvider provider)
15
    {
NEW
16
        if (provider.EncryptCount == 0)
×
17
        {
NEW
18
            throw new AssertionException("Expected at least one encryption operation, but none occurred.");
×
19
        }
20

NEW
21
        return provider;
×
22
    }
23

24
    /// <summary>
25
    /// Asserts that encryption was called a specific number of times.
26
    /// </summary>
27
    /// <param name="provider">The mock encryption provider.</param>
28
    /// <param name="times">The expected number of encryptions.</param>
29
    /// <returns>The provider for chaining.</returns>
30
    /// <exception cref="AssertionException">Thrown when the count doesn't match.</exception>
31
    public static MockEncryptionProvider ShouldHaveEncryptedTimes(this MockEncryptionProvider provider, int times)
32
    {
NEW
33
        if (provider.EncryptCount != times)
×
34
        {
NEW
35
            throw new AssertionException($"Expected {times} encryption operations, but {provider.EncryptCount} occurred.");
×
36
        }
37

NEW
38
        return provider;
×
39
    }
40

41
    /// <summary>
42
    /// Asserts that decryption was called at least once.
43
    /// </summary>
44
    /// <param name="provider">The mock encryption provider.</param>
45
    /// <returns>The provider for chaining.</returns>
46
    /// <exception cref="AssertionException">Thrown when no decryption occurred.</exception>
47
    public static MockEncryptionProvider ShouldHaveDecrypted(this MockEncryptionProvider provider)
48
    {
NEW
49
        if (provider.DecryptCount == 0)
×
50
        {
NEW
51
            throw new AssertionException("Expected at least one decryption operation, but none occurred.");
×
52
        }
53

NEW
54
        return provider;
×
55
    }
56

57
    /// <summary>
58
    /// Asserts that decryption was called a specific number of times.
59
    /// </summary>
60
    /// <param name="provider">The mock encryption provider.</param>
61
    /// <param name="times">The expected number of decryptions.</param>
62
    /// <returns>The provider for chaining.</returns>
63
    /// <exception cref="AssertionException">Thrown when the count doesn't match.</exception>
64
    public static MockEncryptionProvider ShouldHaveDecryptedTimes(this MockEncryptionProvider provider, int times)
65
    {
NEW
66
        if (provider.DecryptCount != times)
×
67
        {
NEW
68
            throw new AssertionException($"Expected {times} decryption operations, but {provider.DecryptCount} occurred.");
×
69
        }
70

NEW
71
        return provider;
×
72
    }
73

74
    /// <summary>
75
    /// Asserts that data of at least the specified size was encrypted.
76
    /// </summary>
77
    /// <param name="provider">The mock encryption provider.</param>
78
    /// <param name="minSize">The minimum data size in bytes.</param>
79
    /// <returns>The provider for chaining.</returns>
80
    /// <exception cref="AssertionException">Thrown when no matching operation was found.</exception>
81
    public static MockEncryptionProvider ShouldHaveEncryptedDataOfSize(this MockEncryptionProvider provider, int minSize)
82
    {
NEW
83
        var encryptOps = provider.Operations.Where(o => o.Type == OperationType.Encrypt).ToList();
×
NEW
84
        if (!encryptOps.Any(o => o.DataSize >= minSize))
×
85
        {
NEW
86
            var maxFound = encryptOps.Count > 0 ? encryptOps.Max(o => o.DataSize) : 0;
×
NEW
87
            throw new AssertionException($"Expected encryption of data at least {minSize} bytes, but maximum was {maxFound} bytes.");
×
88
        }
89

NEW
90
        return provider;
×
91
    }
92

93
    /// <summary>
94
    /// Asserts that data of at least the specified size was decrypted.
95
    /// </summary>
96
    /// <param name="provider">The mock encryption provider.</param>
97
    /// <param name="minSize">The minimum data size in bytes.</param>
98
    /// <returns>The provider for chaining.</returns>
99
    /// <exception cref="AssertionException">Thrown when no matching operation was found.</exception>
100
    public static MockEncryptionProvider ShouldHaveDecryptedDataOfSize(this MockEncryptionProvider provider, int minSize)
101
    {
NEW
102
        var decryptOps = provider.Operations.Where(o => o.Type == OperationType.Decrypt).ToList();
×
NEW
103
        if (!decryptOps.Any(o => o.DataSize >= minSize))
×
104
        {
NEW
105
            var maxFound = decryptOps.Count > 0 ? decryptOps.Max(o => o.DataSize) : 0;
×
NEW
106
            throw new AssertionException($"Expected decryption of data at least {minSize} bytes, but maximum was {maxFound} bytes.");
×
107
        }
108

NEW
109
        return provider;
×
110
    }
111

112
    /// <summary>
113
    /// Asserts that no encryption operations occurred.
114
    /// </summary>
115
    /// <param name="provider">The mock encryption provider.</param>
116
    /// <returns>The provider for chaining.</returns>
117
    /// <exception cref="AssertionException">Thrown when encryption occurred.</exception>
118
    public static MockEncryptionProvider ShouldNotHaveEncrypted(this MockEncryptionProvider provider)
119
    {
NEW
120
        if (provider.EncryptCount > 0)
×
121
        {
NEW
122
            throw new AssertionException($"Expected no encryption operations, but {provider.EncryptCount} occurred.");
×
123
        }
124

NEW
125
        return provider;
×
126
    }
127

128
    /// <summary>
129
    /// Asserts that no decryption operations occurred.
130
    /// </summary>
131
    /// <param name="provider">The mock encryption provider.</param>
132
    /// <returns>The provider for chaining.</returns>
133
    /// <exception cref="AssertionException">Thrown when decryption occurred.</exception>
134
    public static MockEncryptionProvider ShouldNotHaveDecrypted(this MockEncryptionProvider provider)
135
    {
NEW
136
        if (provider.DecryptCount > 0)
×
137
        {
NEW
138
            throw new AssertionException($"Expected no decryption operations, but {provider.DecryptCount} occurred.");
×
139
        }
140

NEW
141
        return provider;
×
142
    }
143

144
    /// <summary>
145
    /// Asserts that the provider is in encrypted mode.
146
    /// </summary>
147
    /// <param name="provider">The mock encryption provider.</param>
148
    /// <returns>The provider for chaining.</returns>
149
    /// <exception cref="AssertionException">Thrown when not in encrypted mode.</exception>
150
    public static MockEncryptionProvider ShouldBeEncrypting(this MockEncryptionProvider provider)
151
    {
NEW
152
        if (!provider.IsEncrypted)
×
153
        {
NEW
154
            throw new AssertionException("Expected provider to be in encrypted mode, but it was in pass-through mode.");
×
155
        }
156

NEW
157
        return provider;
×
158
    }
159

160
    /// <summary>
161
    /// Asserts that the total number of operations (encrypt + decrypt) matches.
162
    /// </summary>
163
    /// <param name="provider">The mock encryption provider.</param>
164
    /// <param name="count">The expected total operation count.</param>
165
    /// <returns>The provider for chaining.</returns>
166
    /// <exception cref="AssertionException">Thrown when the count doesn't match.</exception>
167
    public static MockEncryptionProvider ShouldHaveTotalOperations(this MockEncryptionProvider provider, int count)
168
    {
NEW
169
        var total = provider.Operations.Count;
×
NEW
170
        if (total != count)
×
171
        {
NEW
172
            throw new AssertionException($"Expected {count} total operations, but {total} occurred.");
×
173
        }
174

NEW
175
        return provider;
×
176
    }
177
}
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