TASK 4 ship step 5.5: social bar bug fixes + bar on the live output — direction-snap drag (SocialBarSnap.Decide + ClearValue, local Canvas.Top was overriding the binding), fediverse nodeinfo subdomain probing + load-time heal (settable FediverseSoftware), SocialBarRenderer strip blitted above the flash via a re-read FramePump socialBar seam — 155 tests passing, 0 warnings
This commit is contained in:
@@ -66,7 +66,8 @@ public class FramePumpTests
|
||||
|
||||
private static FramePump NewPump(FakeEncoder encoder, Func<EncoderOptions?>? options = null,
|
||||
Func<Scene?>? scene = null, Func<SceneElement, VideoFrame?>? resolve = null,
|
||||
List<string>? log = null)
|
||||
List<string>? log = null,
|
||||
Func<(VideoFrame? Frame, SocialBarPosition Position)>? socialBar = null)
|
||||
{
|
||||
return new FramePump(
|
||||
sceneProvider: scene ?? (() => BackdropScene()),
|
||||
@@ -83,7 +84,8 @@ public class FramePumpTests
|
||||
}),
|
||||
encoderFactory: () => encoder,
|
||||
log: log != null ? m => log.Add(m) : null,
|
||||
pacingDelay: async (_, _) => await Task.Yield()); // deterministic: no real waits
|
||||
pacingDelay: async (_, _) => await Task.Yield(), // deterministic: no real waits
|
||||
socialBar: socialBar);
|
||||
}
|
||||
|
||||
private static void AssertColor(VideoFrame frame, int x, int y, byte r, byte g, byte b)
|
||||
@@ -163,6 +165,49 @@ public class FramePumpTests
|
||||
Assert.False(pump.IsRunning);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Start_WithSocialBarSeam_PlacesBarAtTopThenBottomEdge()
|
||||
{
|
||||
var red = SceneCompositorTests.Solid(64, 48, 255, 0, 0);
|
||||
var bar = new VideoFrame(64, 8, new byte[64 * 8 * 4]);
|
||||
Array.Fill(bar.BgraPixels, (byte)255); // opaque white strip
|
||||
|
||||
var encoder = new FakeEncoder();
|
||||
var position = SocialBarPosition.Top;
|
||||
using var pump = NewPump(encoder,
|
||||
resolve: e => e is Source { IsBackdrop: true } ? red : null,
|
||||
socialBar: () => (bar, position));
|
||||
|
||||
await pump.StartAsync();
|
||||
await encoder.FrameArrived.Task.WaitAsync(TimeSpan.FromSeconds(5));
|
||||
Assert.NotEmpty(encoder.Frames);
|
||||
AssertColor(encoder.Frames[0], 0, 0, 255, 255, 255); // bar at the top edge
|
||||
|
||||
// Flip to Bottom: the pump re-reads the seam each frame, so a later frame
|
||||
// lands the bar at the bottom edge (SourceRectHeight - bar height) and the
|
||||
// top corner clears back to backdrop.
|
||||
position = SocialBarPosition.Bottom;
|
||||
VideoFrame? flipped = null;
|
||||
var deadline = DateTime.UtcNow.AddSeconds(5);
|
||||
while (DateTime.UtcNow < deadline && flipped == null)
|
||||
{
|
||||
for (var i = 1; i < encoder.Frames.Count; i++)
|
||||
{
|
||||
var f = encoder.Frames[i];
|
||||
if (f.BgraPixels[2] == 255 && f.BgraPixels[1] == 0 && f.BgraPixels[0] == 0)
|
||||
{
|
||||
flipped = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flipped == null) await Task.Delay(10);
|
||||
}
|
||||
Assert.NotNull(flipped);
|
||||
AssertColor(flipped!, 0, 47, 255, 255, 255); // bar sits on the bottom edge
|
||||
|
||||
await pump.StopAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Start_EncoderThrows_RaisesFailed_AndDisposes()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user