Zu Halloween, zur Weihnachtszeit, zum Jahreswechsel, im Sommer — und zu allem, was sonst jemand feiert. **Nach Stichwörtern, nicht nach Genres.** „Stirb langsam" ist kein Familienfilm und trägt trotzdem „christmas". Eine Weihnachtsreihe nach Genres enthielte jeden Zeichentrickfilm und diesen Film nicht. TMDB führt die Stichwörter ohnehin; sie kommen jetzt über `append_to_response` mit und landen in einer eigenen Tabelle, nach demselben Muster wie Genres. Kleingeschrieben abgelegt — TMDB liefert „Christmas" und „christmas" je nach Eintrag, und zwei Schreibweisen wären zwei Stichwörter. **Einstellbar und nicht eingebaut.** Halloween und Weihnachten kennt jeder; der 1. August ist Schweizer Nationalfeiertag, der 4. Juli amerikanischer, und der Geburtstag des Betreibers steht in keiner Bibliothek. Eine feste Liste im Quelltext hiesse: für jeden Anlass eine neue Fassung. Vier sind vorangelegt — als Beispiel, nicht als Meinung darüber, was jemand feiert. **Über den Jahreswechsel hinweg.** „28.12. bis 02.01." ist kein Fehler, sondern der Normalfall für Silvester; ein Vergleich, der nur „von ≤ heute ≤ bis" kennt, fände diesen Zeitraum nie — und die Reihe stünde genau in den Tagen nicht da, für die sie gedacht ist. Geprüft, Tag für Tag, samt der Zusicherung, dass sich die vorangelegten Anlässe an keinem Tag im Jahr überschneiden. **Leer heisst leer.** Gilt heute kein Anlass oder findet er nichts, kommt eine Reihe ohne Namen zurück und der Client zeigt gar keine — statt einer mit Überschrift und nichts darunter. Scheitert der Abruf ganz, fehlt eine Reihe und nicht die Startseite. Bedient wird sie als Text, eine Zeile je Anlass: Name, von, bis, Stichwörter, Genres. Ein Listeneditor mit Zeilen zum Hinzufügen, Verschieben und Löschen wäre viel Oberfläche für etwas, das man dreimal im Jahr anfasst — und es ist dieselbe Form, in der es gespeichert wird. Ein Anlass ohne Stichwort und ohne Genre wird abgewiesen statt stillschweigend geschluckt: er fände nie etwas, und wer ihn eingetragen hat, suchte den Fehler woanders. **Die Stichwörter kommen erst beim nächsten Auffrischen der Metadaten.** Vorhandene Titel tragen noch keine — bis dahin bleibt die Reihe leer. 764 Tests grün, davon 22 neue. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
98 lines
3.6 KiB
C#
98 lines
3.6 KiB
C#
using Flaro.Core.Library;
|
|
|
|
namespace Flaro.Core.Tests;
|
|
|
|
/// <summary>Wann ein saisonaler Anlass gilt.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// <b>Der Fall, an dem eine naive Prüfung scheitert:</b> Silvester geht vom
|
|
/// 28. Dezember bis zum 2. Januar. Ein Vergleich, der nur „von ≤ heute ≤
|
|
/// bis" kennt, fände diesen Zeitraum nie — und die Reihe stünde genau in
|
|
/// den Tagen nicht da, für die sie gedacht ist.
|
|
/// </remarks>
|
|
public class SaisonanlassTests
|
|
{
|
|
private static DateTimeOffset Am(int monat, int tag) =>
|
|
new(2026, monat, tag, 12, 0, 0, TimeSpan.Zero);
|
|
|
|
private static Saisonanlass Anlass(string von, string bis) =>
|
|
new("Probe", von, bis, ["irgendwas"], []);
|
|
|
|
[TestCase(10, 1, true)]
|
|
[TestCase(10, 15, true)]
|
|
[TestCase(11, 1, true)]
|
|
[TestCase(9, 30, false)]
|
|
[TestCase(11, 2, false)]
|
|
public void Ein_Zeitraum_im_Jahr_gilt_von_Rand_zu_Rand(int monat, int tag, bool erwartet) =>
|
|
Assert.That(Anlass("10-01", "11-01").Gilt(Am(monat, tag)), Is.EqualTo(erwartet));
|
|
|
|
[TestCase(12, 28, true)]
|
|
[TestCase(12, 31, true)]
|
|
[TestCase(1, 1, true)]
|
|
[TestCase(1, 2, true)]
|
|
[TestCase(1, 3, false)]
|
|
[TestCase(12, 27, false)]
|
|
[TestCase(6, 15, false)]
|
|
public void Ein_Zeitraum_ueber_den_Jahreswechsel_gilt_auch(int monat, int tag, bool erwartet) =>
|
|
Assert.That(Anlass("12-28", "01-02").Gilt(Am(monat, tag)), Is.EqualTo(erwartet));
|
|
|
|
[Test]
|
|
public void Ein_einzelner_Tag_ist_ein_Zeitraum_von_null_Laenge()
|
|
{
|
|
var august = Anlass("08-01", "08-01");
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(august.Gilt(Am(8, 1)), Is.True);
|
|
Assert.That(august.Gilt(Am(8, 2)), Is.False);
|
|
Assert.That(august.Gilt(Am(7, 31)), Is.False);
|
|
});
|
|
}
|
|
|
|
[TestCase("")]
|
|
[TestCase("Oktober")]
|
|
[TestCase("13-01")]
|
|
[TestCase("10-32")]
|
|
[TestCase("10")]
|
|
public void Ein_unleserliches_Datum_gilt_nie(string von) =>
|
|
Assert.That(Anlass(von, "11-01").Gilt(Am(10, 15)), Is.False);
|
|
|
|
/// <summary>Ein Anlass ohne Stichwort und ohne Genre fände nie etwas.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// Ihn stillschweigend zu speichern hiesse, den Benutzer den Fehler
|
|
/// woanders suchen zu lassen — die Reihe erschiene einfach nicht.
|
|
/// </remarks>
|
|
[Test]
|
|
public void Ohne_Stichwort_und_ohne_Genre_ist_ein_Anlass_unbrauchbar()
|
|
{
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(new Saisonanlass("Leer", "10-01", "11-01", [], []).Brauchbar, Is.False);
|
|
Assert.That(new Saisonanlass("", "10-01", "11-01", ["x"], []).Brauchbar, Is.False);
|
|
Assert.That(new Saisonanlass("Mit Genre", "10-01", "11-01", [], ["Horror"]).Brauchbar, Is.True);
|
|
Assert.That(new Saisonanlass("Mit Wort", "10-01", "11-01", ["x"], []).Brauchbar, Is.True);
|
|
});
|
|
}
|
|
|
|
/// <summary>Die Vorgabe deckt das Jahr ab, ohne sich zu überschneiden.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// Zwei gleichzeitig geltende Anlässe wären kein Fehler — der Server
|
|
/// nimmt den ersten —, aber einer davon stünde nie da, und das merkte
|
|
/// niemand.
|
|
/// </remarks>
|
|
[Test]
|
|
public void Die_vorangelegten_Anlaesse_ueberschneiden_sich_nicht()
|
|
{
|
|
for (var tag = new DateTimeOffset(2026, 1, 1, 12, 0, 0, TimeSpan.Zero);
|
|
tag.Year == 2026;
|
|
tag = tag.AddDays(1))
|
|
{
|
|
var geltend = Saisonanlass.Vorgabe.Where(a => a.Gilt(tag)).Select(a => a.Name).ToList();
|
|
Assert.That(geltend, Has.Count.LessThanOrEqualTo(1),
|
|
$"am {tag:dd.MM.} gelten mehrere: {string.Join(", ", geltend)}");
|
|
}
|
|
}
|
|
}
|