using Flaro.Core.Library;
namespace Flaro.Core.Tests;
public class FilmNamenTests
{
[TestCase("The Matrix (1999).mkv", "The Matrix", 1999)]
[TestCase("The.Matrix.1999.1080p.BluRay.x264-GROUP.mkv", "The Matrix", 1999)]
[TestCase("The Matrix 1999 2160p UHD BluRay REMUX HDR.mkv", "The Matrix", 1999)]
[TestCase("Der.Untergang.2004.German.1080p.BluRay.x264-ENCOUNTERS.mkv", "Der Untergang", 2004)]
[TestCase("Das Boot (1981) [1080p].mp4", "Das Boot", 1981)]
[TestCase("Inception.2010.EXTENDED.1080p.BluRay.DTS-HD.MA.5.1.x264.mkv", "Inception", 2010)]
[TestCase("Spirited Away.m4v", "Spirited Away", null)]
[TestCase("Männer.die.auf.Ziegen.starren.2009.German.DL.1080p.mkv", "Männer die auf Ziegen starren", 2009)]
public void Titel_und_Jahr_werden_erkannt(string datei, string titel, int? jahr)
{
var name = FileNames.ParseMovie(datei);
Assert.That(name.Title, Is.EqualTo(titel));
Assert.That(name.Year, Is.EqualTo(jahr));
}
/// Eine Zahl im Titel ist kein Jahr.
///
///
/// Der Fall, an dem sich die Regel entscheidet. „2049" sähe wie ein
/// Jahr aus; es liegt nur weit in der Zukunft. Ohne diese Grenze hiesse der
/// Film „Blade Runner", erschienen 2049 — und keine Metadatenquelle der
/// Welt findet ihn so.
///
[TestCase("Blade Runner 2049 (2017).mkv", "Blade Runner 2049", 2017)]
[TestCase("Blade.Runner.2049.2017.1080p.mkv", "Blade Runner 2049", 2017)]
[TestCase("2012 (2009).mkv", "2012", 2009)]
[TestCase("1917 (2019).mkv", "1917", 2019)]
[TestCase("300 (2006).mkv", "300", 2006)]
public void Zahlen_im_Titel_werden_nicht_fuer_Jahre_gehalten(string datei, string titel, int jahr)
{
var name = FileNames.ParseMovie(datei);
Assert.That(name.Title, Is.EqualTo(titel));
Assert.That(name.Year, Is.EqualTo(jahr));
}
/// Wer von Hand benennt, meint seine Punkte so.
[Test]
public void Punkte_in_einem_von_Hand_benannten_Titel_bleiben_stehen()
{
Assert.That(FileNames.ParseMovie("S.W.A.T. (2003).mkv").Title, Is.EqualTo("S.W.A.T."));
Assert.That(FileNames.ParseMovie("Wall-E (2008).mkv").Title, Is.EqualTo("Wall-E"));
}
[Test]
public void Ohne_erkennbares_Muster_bleibt_der_Dateiname_stehen()
{
// Lieber ein unschöner Titel als ein leerer: so ist der Film wenigstens
// zu finden und von Hand zu berichtigen.
Assert.That(FileNames.ParseMovie("irgendwas.mkv").Title, Is.EqualTo("irgendwas"));
Assert.That(FileNames.ParseMovie("1080p.mkv").Title, Is.EqualTo("1080p"));
}
}
public class FolgenNamenTests
{
[TestCase("Notruf.Hafenkante.S01E01.German.1080p.WEB-DL.x264-GRP.mkv", "Notruf Hafenkante", 1, 1)]
[TestCase("Notruf Hafenkante - S01E01 - Der Fall.mkv", "Notruf Hafenkante", 1, 1)]
[TestCase("Breaking Bad S05E14 Ozymandias.mkv", "Breaking Bad", 5, 14)]
[TestCase("The.Wire.s02e05.1080p.mkv", "The Wire", 2, 5)]
[TestCase("Dark - 1x03 - Gestern und heute.mkv", "Dark", 1, 3)]
[TestCase("Tatort.01x09.mkv", "Tatort", 1, 9)]
[TestCase("Show S1E2.mkv", "Show", 1, 2)]
[TestCase("Serie.S01.E07.1080p.mkv", "Serie", 1, 7)]
public void Serie_Staffel_und_Folge_werden_erkannt(string datei, string serie, int staffel, int folge)
{
var name = FileNames.ParseEpisode(datei);
Assert.That(name, Is.Not.Null, $"„{datei}“ wurde gar nicht als Folge erkannt");
Assert.That(name!.SeriesTitle, Is.EqualTo(serie));
Assert.That(name.Season, Is.EqualTo(staffel));
Assert.That(name.Episode, Is.EqualTo(folge));
}
[Test]
public void Der_Folgentitel_wird_mitgenommen_wenn_einer_dasteht()
{
var name = FileNames.ParseEpisode("Notruf Hafenkante - S01E01 - Der Fall.mkv");
Assert.That(name!.EpisodeTitle, Is.EqualTo("Der Fall"));
}
[Test]
public void Technik_hinter_der_Nummer_ist_kein_Folgentitel()
{
var name = FileNames.ParseEpisode("Breaking.Bad.S05E14.1080p.BluRay.x264-GRP.mkv");
Assert.That(name!.EpisodeTitle, Is.Null);
}
/// Doppelfolgen zählen ab der ersten.
[Test]
public void Eine_Doppelfolge_wird_der_ersten_Nummer_zugeordnet()
{
var name = FileNames.ParseEpisode("Serie.S02E05E06.mkv");
Assert.That(name!.Season, Is.EqualTo(2));
Assert.That(name.Episode, Is.EqualTo(5));
}
/// Ohne Nummer wird nichts geraten.
///
///
/// Eine erfundene Staffel 1 wäre schlimmer als gar keine Angabe: der Titel
/// landete unter einer Serie, zu der er nicht gehört, und niemand fände ihn
/// dort je wieder.
///
[TestCase("The Matrix (1999).mkv")]
[TestCase("Irgendein Film.mkv")]
[TestCase("Dokumentation ueber 1999.mkv")]
public void Ohne_Folgennummer_gibt_es_keine_Folge(string datei)
{
Assert.That(FileNames.ParseEpisode(datei), Is.Null);
}
/// Eine Auflösung ist keine Folgennummer.
[Test]
public void Die_Aufloesung_wird_nicht_fuer_eine_Folge_gehalten()
{
// „1920x1080" sähe in der Kreuzschreibweise wie Staffel 1920 aus.
Assert.That(FileNames.ParseEpisode("Film.1920x1080.mkv"), Is.Null);
}
}
public class MedienDateienTests
{
[TestCase("film.mkv", true)]
[TestCase("film.MP4", true)]
[TestCase("film.m2ts", true)]
[TestCase("film.nfo", false)]
[TestCase("film.srt", false)]
[TestCase("poster.jpg", false)]
[TestCase("Thumbs.db", false)]
[TestCase(".DS_Store", false)]
[TestCase(".versteckt.mkv", false)]
public void Nur_Videodateien_zaehlen(string name, bool erwartet)
{
Assert.That(MediaExtensions.IsVideo(name), Is.EqualTo(erwartet));
}
/// Ein laufender Download ist noch kein Film.
///
///
/// Ihn aufzunehmen hiesse: ein Titel erscheint, verschwindet wieder, und
/// wer ihn dazwischen antippt, sieht einen Film, der mittendrin abbricht.
///
[TestCase("film.mkv.part")]
[TestCase("film.mkv.!qb")]
[TestCase("film.mkv.crdownload")]
public void Unfertige_Dateien_zaehlen_nicht(string name)
{
Assert.That(MediaExtensions.IsVideo(name), Is.False);
}
/// @eaDir enthält Kopien jeder Datei — mitscannen verdoppelt die Mediathek.
[TestCase("@eaDir", true)]
[TestCase("#recycle", true)]
[TestCase(".git", true)]
[TestCase("Extras", true)]
[TestCase("Season 01", false)]
[TestCase("Filme", false)]
public void Bestimmte_Ordner_werden_uebersprungen(string name, bool erwartet)
{
Assert.That(MediaExtensions.IsSkippedDirectory(name), Is.EqualTo(erwartet));
}
}
/// Woher der Serienname kommt, wenn der Dateiname ihn nicht nennt.
///
///
/// Der Fall, der aus einer Serie siebenhundert machte. Heisst eine
/// Datei nur „S01E01.mkv", steht vor der Folgennummer nichts — und bis dahin
/// wurde der ganze Dateiname zum Serientitel. Zwanzig Folgen ergaben zwanzig
/// Serien namens „S01E01", „S01E02", und so weiter.
///
public class SerieAusOrdnerTests
{
[TestCase("Dark/Staffel 1/S01E01.mkv", "Dark")]
[TestCase("Dark/Season 2/S02E05.mkv", "Dark")]
[TestCase("Doctor Who (2005)/Staffel 12/S12E04.mkv", "Doctor Who")]
[TestCase("Serien/Dark/S01E01.mkv", "Dark")]
[TestCase("Dark/Specials/S00E01.mkv", "Dark")]
public void Ohne_Namen_in_der_Datei_gilt_der_Ordner(string pfad, string erwartet) =>
Assert.That(FileNames.ParseEpisode(pfad)?.SeriesTitle, Is.EqualTo(erwartet));
/// Steht er im Dateinamen, hat er Vorrang — er ist genauer.
[Test]
public void Der_Dateiname_sticht_den_Ordner() =>
Assert.That(FileNames.ParseEpisode("Irgendwas/Staffel 1/Dark - S01E01 - Geheimnisse.mkv")?.SeriesTitle,
Is.EqualTo("Dark"));
[Test]
public void Staffel_und_Folge_bleiben_richtig()
{
var name = FileNames.ParseEpisode("Dark/Staffel 2/S02E05.mkv");
Assert.That(name!.Season, Is.EqualTo(2));
Assert.That(name.Episode, Is.EqualTo(5));
}
}
/// Mit Wurzel entscheidet der Ordner — allein.
///
///
/// Der Fall, der aus einer Serie siebenhundert machte. Dateien wie
/// „S01E001_Aang.mkv" tragen vor der Folgennummer nichts, also wurde der ganze
/// Dateiname zum Serientitel. Und „Doctor Who (2005) - S12E04.mkv" im Ordner
/// „Doctor Who" ergab zwei Serien, weil die Jahresangabe nur im Dateinamen
/// stand. Der Ordner ist die verlässlichere Angabe: den hat ein Mensch
/// angelegt.
///
public class SerieAusDerWurzelTests
{
private const string Wurzel = "/media/Serien";
[TestCase("/media/Serien/Pingu/S01E001_Willkommen.mkv", "Pingu")]
[TestCase("/media/Serien/Pingu/Staffel 1/S01E002_Volltreffer.mkv", "Pingu")]
[TestCase("/media/Serien/Avatar/Buch 1/S01E001_Aang.mkv", "Avatar")]
[TestCase("/media/Serien/Nachtstreife/S01E05_Folge 5.mkv", "Nachtstreife")]
public void Alles_im_Serienordner_gehoert_zu_dieser_Serie(string pfad, string erwartet) =>
Assert.That(FileNames.ParseEpisode(pfad, Wurzel)?.SeriesTitle, Is.EqualTo(erwartet));
/// Auch dann, wenn der Dateiname etwas anderes behauptet.
[Test]
public void Der_Ordner_sticht_den_Dateinamen() =>
Assert.That(
FileNames.ParseEpisode("/media/Serien/Doctor Who/Staffel 12/Doctor Who (2005) - S12E04.mkv", Wurzel)
?.SeriesTitle,
Is.EqualTo("Doctor Who"));
/// Zwei Schreibweisen im Dateinamen, ein Ordner, eine Serie.
[Test]
public void Zwei_Dateien_desselben_Ordners_ergeben_eine_Serie()
{
var a = FileNames.ParseEpisode("/media/Serien/Dark/S01E01.mkv", Wurzel);
var b = FileNames.ParseEpisode("/media/Serien/Dark/Staffel 1/Dark (2017) - S01E02.mkv", Wurzel);
Assert.That(a!.SeriesTitle, Is.EqualTo(b!.SeriesTitle));
Assert.That(a.SeriesTitle, Is.EqualTo("Dark"));
}
/// Staffel und Folge liest weiterhin der Dateiname.
[Test]
public void Nummern_kommen_weiter_aus_dem_Dateinamen()
{
var name = FileNames.ParseEpisode("/media/Serien/Dark/Staffel 2/S02E05_Titel.mkv", Wurzel);
Assert.That(name!.Season, Is.EqualTo(2));
Assert.That(name.Episode, Is.EqualTo(5));
Assert.That(name.EpisodeTitle, Is.EqualTo("Titel"));
}
/// Liegt die Datei direkt in der Wurzel, gibt es keinen Ordner, der sie benennt.
[Test]
public void Direkt_in_der_Wurzel_gilt_der_Dateiname() =>
Assert.That(FileNames.ParseEpisode("/media/Serien/Dark - S01E01.mkv", Wurzel)?.SeriesTitle,
Is.EqualTo("Dark"));
}
/// Benennungen, die im echten Bestand vorkamen und durchfielen.
///
///
/// Diese Namen sind nicht ausgedacht. Jeder davon stammt aus einem
/// Protokoll, in dem 3559 von 5884 Dateien als „nicht zugeordnet" standen —
/// und aus 95 Serien wurden dadurch 58. Erfundene Testnamen hatten den Fehler
/// nicht gefunden: sie trugen alle ein Leerzeichen vor der Folgennummer.
///
public class EchteBenennungen
{
private const string Wurzel = "/media/Serien";
/// Der Unterstrich — 3445 Dateien, und die teuerste Zeile des Tages.
///
///
/// \b sitzt zwischen Wortzeichen und Nicht-Wortzeichen. Der
/// Unterstrich ist selbst ein Wortzeichen, also gibt es zwischen r
/// und S keine Grenze — und der ganze Mediathek-Bestand fiel durch.
///
[Test]
public void Unterstrich_vor_der_Folgennummer()
{
var name = FileNames.ParseEpisode(
$"{Wurzel}/The Good Doctor/S02/The Good Doctor_S02E18_Trampolin.mkv", Wurzel);
Assert.That(name, Is.Not.Null);
Assert.That(name!.SeriesTitle, Is.EqualTo("The Good Doctor"));
Assert.That(name.Season, Is.EqualTo(2));
Assert.That(name.Episode, Is.EqualTo(18));
Assert.That(name.EpisodeTitle, Is.EqualTo("Trampolin"));
}
/// Mediatheken nummerieren nach Jahr: S2024E04.
[Test]
public void Jahreszahl_als_Staffel()
{
var name = FileNames.ParseEpisode(
$"{Wurzel}/Die Anstalt/Die Anstalt_S2024E04_Die Anstalt vom 11_ Juni 2024.mkv", Wurzel);
Assert.That(name, Is.Not.Null);
Assert.That(name!.SeriesTitle, Is.EqualTo("Die Anstalt"));
Assert.That(name.Season, Is.EqualTo(2024));
Assert.That(name.Episode, Is.EqualTo(4));
}
/// „Folge 12" ist eine Folgennummer, nur auf Deutsch.
[Test]
public void Folge_auf_Deutsch()
{
var name = FileNames.ParseEpisode(
$"{Wurzel}/Weihnachtsmann & Co. KG (1997)/"
+ "Weihnachtsmann & Co. KG # Folge 12 # Strafe muss sein # Ganze Folge # TOGGO Serien.mp4",
Wurzel);
Assert.That(name, Is.Not.Null);
Assert.That(name!.SeriesTitle, Is.EqualTo("Weihnachtsmann & Co. KG"));
Assert.That(name.Season, Is.EqualTo(1), "Ohne Staffelordner gilt die Übereinkunft: Staffel 1.");
Assert.That(name.Episode, Is.EqualTo(12));
}
/// Steht die Staffel am Ordner, wird sie nicht erfunden.
[Test]
public void Folge_mit_Staffel_aus_dem_Ordner()
{
var name = FileNames.ParseEpisode(
$"{Wurzel}/Irgendeine Serie/Season 4/Irgendeine Serie - Folge 7.mp4", Wurzel);
Assert.That(name, Is.Not.Null);
Assert.That(name!.Season, Is.EqualTo(4));
Assert.That(name.Episode, Is.EqualTo(7));
}
/// Was wirklich keine Nummer trägt, bleibt liegen.
///
///
/// Fünf Dateien im echten Bestand sind so: ein Titel in einem
/// Staffelordner, sonst nichts. Eine Nummer dafür zu erfinden hiesse, sie
/// an eine beliebige Stelle zu setzen — dann lieber sichtbar liegen lassen.
///
[Test]
public void Ein_blosser_Titel_bleibt_unerkannt()
{
Assert.That(
FileNames.ParseEpisode($"{Wurzel}/Nachtstreife (2020)/Season 4/Endstation Zelle.mp4", Wurzel),
Is.Null);
}
/// Die Gründe müssen auseinanderhalten, was Verschiedenes verlangt.
[Test]
public void Der_Grund_benennt_das_Richtige()
{
Assert.That(
FileNames.WarumNicht($"{Wurzel}/Nachtstreife (2020)/Season 4/Endstation Zelle.mp4", Wurzel),
Does.Contain("keine Folgennummer"));
}
}