using Flaro.Core.Media;
namespace Flaro.Core.Tests;
/// Wo der Abspann eines Films anfängt.
///
///
/// Mit erfundenen Messreihen statt mit Filmen. Geprüft wird das
/// Beurteilen, nicht ob ffmpeg rechnen kann. Die Zahlen stammen aus einer
/// Messung an einem erzeugten Film: Handlung 125, Abspann 18.
///
public class AbspannkanteTests
{
private static readonly Abspannregeln Regeln = Abspannregeln.Vorgabe;
/// Eine Reihe von Messpunkten im Abstand von zehn Sekunden.
///
/// Ab wann dunkel. null heisst: nie.
private static List Reihe(double von, double bis, double? abspannAb)
{
var proben = new List();
for (var t = von; t <= bis; t += 10)
proben.Add(new Bildprobe(t, abspannAb is { } ab && t >= ab ? 18 : 125));
return proben;
}
[Test]
public void Eine_dunkle_Strecke_bis_zum_Ende_ist_der_Abspann()
{
var proben = Reihe(0, 600, abspannAb: 420);
Assert.That(Abspannkante.Suchen(proben, Regeln), Is.EqualTo(420));
}
/// Ein Film, der hell endet, hat keinen erkennbaren Abspann.
///
///
/// Namen über laufendem Bild — Marvel, Pixar, jede zweite Komödie. Kein
/// Fund ist hier die richtige Antwort: ein geratener Knopf schnitte
/// Handlung weg.
///
[Test]
public void Ohne_dunkles_Ende_kein_Fund()
{
Assert.That(Abspannkante.Suchen(Reihe(0, 600, abspannAb: null), Regeln), Is.Null);
}
/// Eine Schwarzblende mitten im Film zählt nicht.
[Test]
public void Eine_Schwarzblende_in_der_Mitte_zaehlt_nicht()
{
var proben = Reihe(0, 600, abspannAb: null);
for (var i = 20; i < 30; i++) proben[i] = proben[i] with { Helligkeit = 10 };
Assert.That(Abspannkante.Suchen(proben, Regeln), Is.Null,
"sie hält nicht bis zum Ende durch");
}
/// Eine Szene nach dem Abspann nimmt den Fund weg.
///
///
/// Lieber keine Marke als eine, die über die Szene hinwegspringt.
///
[Test]
public void Eine_Szene_nach_dem_Abspann_nimmt_den_Fund_weg()
{
var proben = Reihe(0, 600, abspannAb: 420);
for (var i = proben.Count - 5; i < proben.Count; i++)
proben[i] = proben[i] with { Helligkeit = 120 };
Assert.That(Abspannkante.Suchen(proben, Regeln), Is.Null);
}
/// Eine helle Schrifttafel mittendrin bricht die Strecke nicht.
[Test]
public void Eine_kurze_helle_Tafel_bricht_nichts()
{
var proben = Reihe(0, 600, abspannAb: 420);
// Zwei Proben, also zwanzig Sekunden, sind hell.
proben[50] = proben[50] with { Helligkeit = 140 };
proben[51] = proben[51] with { Helligkeit = 140 };
Assert.That(Abspannkante.Suchen(proben, Regeln), Is.EqualTo(420));
}
/// Zwanzig Sekunden Dunkelheit sind kein Abspann.
[Test]
public void Zu_kurz_zaehlt_nicht()
{
Assert.That(Abspannkante.Suchen(Reihe(0, 600, abspannAb: 580), Regeln), Is.Null);
}
/// Ein halber Film im Dunkeln ist ein Fehlfund.
[Test]
public void Zu_lang_zaehlt_auch_nicht()
{
Assert.That(Abspannkante.Suchen(Reihe(0, 3600, abspannAb: 600), Regeln), Is.Null);
}
[Test]
public void Die_letzte_helle_Probe_begrenzt_die_Suche()
{
var proben = Reihe(0, 600, abspannAb: 420);
Assert.That(Abspannkante.HellDavor(proben, 420, Regeln), Is.EqualTo(410));
}
// ---------- Nachmessen ----------
/// Die binäre Suche findet die Kante auf vier Sekunden genau.
[Test]
public async Task Die_Kante_wird_eingegrenzt()
{
const double echteKante = 417.3;
var sonden = 0;
var kante = await Abspannkante.VerfeinernAsync(410, 420, Regeln, stelle =>
{
sonden++;
return Task.FromResult(stelle >= echteKante ? 18 : 125);
});
Assert.Multiple(() =>
{
Assert.That(kante, Is.EqualTo(echteKante).Within(4));
Assert.That(kante, Is.GreaterThanOrEqualTo(echteKante),
"lieber ein paar Sekunden Abspann zu viel als eine Sekunde Handlung");
Assert.That(sonden, Is.LessThanOrEqualTo(4), "zehn Sekunden auf vier: zwei Halbierungen");
});
}
/// Antwortet eine Sonde nicht, gilt der grobe Fund.
[Test]
public async Task Ohne_Antwort_bleibt_es_beim_groben_Fund()
{
var kante = await Abspannkante.VerfeinernAsync(
410, 420, Regeln, _ => Task.FromResult(null));
Assert.That(kante, Is.EqualTo(420));
}
/// Ein schon enger Bereich braucht keine Sonde.
[Test]
public async Task Ein_enger_Bereich_wird_nicht_angefasst()
{
var sonden = 0;
var kante = await Abspannkante.VerfeinernAsync(418, 420, Regeln, _ =>
{
sonden++;
return Task.FromResult(18);
});
Assert.Multiple(() =>
{
Assert.That(kante, Is.EqualTo(420));
Assert.That(sonden, Is.Zero);
});
}
}