Add back all old emby tests

pull/2105/head
Bond_009 5 years ago
parent 935525e77a
commit 35151553e3

@ -2,6 +2,7 @@ using System;
using System.Linq;
using System.Text.RegularExpressions;
using Emby.Naming.Video;
using MediaBrowser.Model.Entities;
namespace Emby.Naming.Common
{
@ -173,7 +174,7 @@ namespace Emby.Naming.Common
CleanDateTimes = new[]
{
@"(.+[^ _\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9][0-9]|20[0-1][0-9])([ _\,\.\(\)\[\]\-][^0-9]|$)"
@"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19[0-9][0-9]|20[0-1][0-9])([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9][0-9]|20[0-1][0-9])*"
};
CleanStrings = new[]
@ -336,7 +337,7 @@ namespace Emby.Naming.Common
// *** End Kodi Standard Naming
                // [bar] Foo - 1 [baz]
                // [bar] Foo - 1 [baz]
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>(\w+\s*?)+?)[-\s_]+(?<epnumber>\d+).*$")
{
IsNamed = true
@ -420,126 +421,126 @@ namespace Emby.Naming.Common
{
new ExtraRule
{
ExtraType = "trailer",
ExtraType = ExtraType.Trailer,
RuleType = ExtraRuleType.Filename,
Token = "trailer",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "trailer",
ExtraType = ExtraType.Trailer,
RuleType = ExtraRuleType.Suffix,
Token = "-trailer",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "trailer",
ExtraType = ExtraType.Trailer,
RuleType = ExtraRuleType.Suffix,
Token = ".trailer",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "trailer",
ExtraType = ExtraType.Trailer,
RuleType = ExtraRuleType.Suffix,
Token = "_trailer",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "trailer",
ExtraType = ExtraType.Trailer,
RuleType = ExtraRuleType.Suffix,
Token = " trailer",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "sample",
ExtraType = ExtraType.Sample,
RuleType = ExtraRuleType.Filename,
Token = "sample",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "sample",
ExtraType = ExtraType.Sample,
RuleType = ExtraRuleType.Suffix,
Token = "-sample",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "sample",
ExtraType = ExtraType.Sample,
RuleType = ExtraRuleType.Suffix,
Token = ".sample",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "sample",
ExtraType = ExtraType.Sample,
RuleType = ExtraRuleType.Suffix,
Token = "_sample",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "sample",
ExtraType = ExtraType.Sample,
RuleType = ExtraRuleType.Suffix,
Token = " sample",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "themesong",
ExtraType = ExtraType.ThemeSong,
RuleType = ExtraRuleType.Filename,
Token = "theme",
MediaType = MediaType.Audio
},
new ExtraRule
{
ExtraType = "scene",
ExtraType = ExtraType.Scene,
RuleType = ExtraRuleType.Suffix,
Token = "-scene",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "clip",
ExtraType = ExtraType.Clip,
RuleType = ExtraRuleType.Suffix,
Token = "-clip",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "interview",
ExtraType = ExtraType.Interview,
RuleType = ExtraRuleType.Suffix,
Token = "-interview",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "behindthescenes",
ExtraType = ExtraType.BehindTheScenes,
RuleType = ExtraRuleType.Suffix,
Token = "-behindthescenes",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "deletedscene",
ExtraType = ExtraType.DeletedScene,
RuleType = ExtraRuleType.Suffix,
Token = "-deleted",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "featurette",
ExtraType = ExtraType.Clip,
RuleType = ExtraRuleType.Suffix,
Token = "-featurette",
MediaType = MediaType.Video
},
new ExtraRule
{
ExtraType = "short",
ExtraType = ExtraType.Clip,
RuleType = ExtraRuleType.Suffix,
Token = "-short",
MediaType = MediaType.Video

@ -4,7 +4,7 @@ using System.Text.RegularExpressions;
namespace Emby.Naming.Video
{
/// <summary>
/// http://kodi.wiki/view/Advancedsettings.xml#video
/// <see href="http://kodi.wiki/view/Advancedsettings.xml#video" />.
/// </summary>
public class CleanStringParser
{

@ -20,7 +20,7 @@ namespace Emby.Naming.Video
{
return _options.VideoExtraRules
.Select(i => GetExtraInfo(path, i))
.FirstOrDefault(i => !string.IsNullOrEmpty(i.ExtraType)) ?? new ExtraResult();
.FirstOrDefault(i => i.ExtraType != null) ?? new ExtraResult();
}
private ExtraResult GetExtraInfo(string path, ExtraRule rule)

@ -1,3 +1,5 @@
using MediaBrowser.Model.Entities;
namespace Emby.Naming.Video
{
public class ExtraResult
@ -6,7 +8,8 @@ namespace Emby.Naming.Video
/// Gets or sets the type of the extra.
/// </summary>
/// <value>The type of the extra.</value>
public string ExtraType { get; set; }
public ExtraType? ExtraType { get; set; }
/// <summary>
/// Gets or sets the rule.
/// </summary>

@ -9,16 +9,19 @@ namespace Emby.Naming.Video
/// </summary>
/// <value>The token.</value>
public string Token { get; set; }
/// <summary>
/// Gets or sets the type of the extra.
/// </summary>
/// <value>The type of the extra.</value>
public string ExtraType { get; set; }
public MediaBrowser.Model.Entities.ExtraType ExtraType { get; set; }
/// <summary>
/// Gets or sets the type of the rule.
/// </summary>
/// <value>The type of the rule.</value>
public ExtraRuleType RuleType { get; set; }
/// <summary>
/// Gets or sets the type of the media.
/// </summary>

@ -11,14 +11,14 @@ namespace Emby.Naming.Video
{
if (path == null)
{
return default(StubResult);
return default;
}
var extension = Path.GetExtension(path);
if (!options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
return default(StubResult);
return default;
}
var result = new StubResult()

@ -1,3 +1,5 @@
using MediaBrowser.Model.Entities;
namespace Emby.Naming.Video
{
/// <summary>
@ -30,10 +32,10 @@ namespace Emby.Naming.Video
public int? Year { get; set; }
/// <summary>
/// Gets or sets the type of the extra, e.g. trailer, theme song, behing the scenes, etc.
/// Gets or sets the type of the extra, e.g. trailer, theme song, behind the scenes, etc.
/// </summary>
/// <value>The type of the extra.</value>
public string ExtraType { get; set; }
public ExtraType? ExtraType { get; set; }
/// <summary>
/// Gets or sets the extra rule.

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Emby.Naming.Common;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
namespace Emby.Naming.Video
@ -29,7 +30,7 @@ namespace Emby.Naming.Video
// Filter out all extras, otherwise they could cause stacks to not be resolved
// See the unit test TestStackedWithTrailer
var nonExtras = videoInfos
.Where(i => string.IsNullOrEmpty(i.ExtraType))
.Where(i => i.ExtraType == null)
.Select(i => new FileSystemMetadata
{
FullName = i.Path,
@ -76,7 +77,7 @@ namespace Emby.Naming.Video
}
var standaloneMedia = remainingFiles
.Where(i => string.IsNullOrEmpty(i.ExtraType))
.Where(i => i.ExtraType == null)
.ToList();
foreach (var media in standaloneMedia)
@ -145,7 +146,7 @@ namespace Emby.Naming.Video
if (list.Count == 1)
{
var trailers = remainingFiles
.Where(i => string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase))
.Where(i => i.ExtraType == ExtraType.Trailer)
.ToList();
list[0].Extras.AddRange(trailers);
@ -226,7 +227,7 @@ namespace Emby.Naming.Video
}
return remainingFiles
.Where(i => !string.IsNullOrEmpty(i.ExtraType))
.Where(i => i.ExtraType == null)
.Where(i => baseNames.Any(b => i.FileNameWithoutExtension.StartsWith(b, StringComparison.OrdinalIgnoreCase)))
.ToList();
}

@ -91,7 +91,7 @@ namespace Emby.Naming.Video
{
var cleanDateTimeResult = CleanDateTime(name);
if (string.IsNullOrEmpty(extraResult.ExtraType))
if (extraResult.ExtraType == null)
{
name = CleanString(cleanDateTimeResult.Name).Name;
}

@ -2556,7 +2556,7 @@ namespace Emby.Server.Implementations.Library
if (currentVideo != null)
{
files.AddRange(currentVideo.Extras.Where(i => string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path)));
files.AddRange(currentVideo.Extras.Where(i => i.ExtraType == ExtraType.Trailer).Select(i => _fileSystem.GetFileInfo(i.Path)));
}
var resolvers = new IItemResolver[]
@ -2606,7 +2606,7 @@ namespace Emby.Server.Implementations.Library
if (currentVideo != null)
{
files.AddRange(currentVideo.Extras.Where(i => !string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path)));
files.AddRange(currentVideo.Extras.Where(i => i.ExtraType != ExtraType.Trailer).Select(i => _fileSystem.GetFileInfo(i.Path)));
}
return ResolvePaths(files, directoryService, null, new LibraryOptions(), null)
@ -2710,7 +2710,7 @@ namespace Emby.Server.Implementations.Library
if (!string.Equals(newPath, path, StringComparison.Ordinal))
{
if (to.IndexOf('/') != -1)
if (to.IndexOf('/', StringComparison.Ordinal) != -1)
{
newPath = newPath.Replace('\\', '/');
}
@ -2731,30 +2731,7 @@ namespace Emby.Server.Implementations.Library
var result = resolver.GetExtraInfo(item.Path);
if (string.Equals(result.ExtraType, "deletedscene", StringComparison.OrdinalIgnoreCase))
{
item.ExtraType = ExtraType.DeletedScene;
}
else if (string.Equals(result.ExtraType, "behindthescenes", StringComparison.OrdinalIgnoreCase))
{
item.ExtraType = ExtraType.BehindTheScenes;
}
else if (string.Equals(result.ExtraType, "interview", StringComparison.OrdinalIgnoreCase))
{
item.ExtraType = ExtraType.Interview;
}
else if (string.Equals(result.ExtraType, "scene", StringComparison.OrdinalIgnoreCase))
{
item.ExtraType = ExtraType.Scene;
}
else if (string.Equals(result.ExtraType, "sample", StringComparison.OrdinalIgnoreCase))
{
item.ExtraType = ExtraType.Sample;
}
else
{
item.ExtraType = ExtraType.Clip;
}
item.ExtraType = result.ExtraType;
}
public List<PersonInfo> GetPeople(InternalPeopleQuery query)

@ -3,20 +3,23 @@ namespace MediaBrowser.Model.Entities
/// <summary>
/// Class MediaType
/// </summary>
public class MediaType
public static class MediaType
{
/// <summary>
/// The video
/// </summary>
public const string Video = "Video";
/// <summary>
/// The audio
/// </summary>
public const string Audio = "Audio";
/// <summary>
/// The photo
/// </summary>
public const string Photo = "Photo";
/// <summary>
/// The book
/// </summary>

@ -24,6 +24,8 @@
<Rule Id="SA1413" Action="None" />
<!-- disable warning SA1512: Single-line comments must not be followed by blank line -->
<Rule Id="SA1512" Action="None" />
<!-- disable warning SA1515: Single-line comment should be preceded by blank line -->
<Rule Id="SA1515" Action="None" />
<!-- disable warning SA1633: The file header is missing or not located at the top of the file -->
<Rule Id="SA1633" Action="None" />
</Rules>

@ -0,0 +1,57 @@
using Emby.Naming.Audio;
using Emby.Naming.Common;
using Xunit;
namespace Jellyfin.Naming.Tests.Music
{
public class MultiDiscAlbumTests
{
[Fact]
public void TestMultiDiscAlbums()
{
Assert.False(IsMultiDiscAlbumFolder(@"blah blah"));
Assert.False(IsMultiDiscAlbumFolder(@"d:/music\weezer/03 Pinkerton"));
Assert.False(IsMultiDiscAlbumFolder(@"d:/music/michael jackson/Bad (2012 Remaster)"));
Assert.True(IsMultiDiscAlbumFolder(@"cd1"));
Assert.True(IsMultiDiscAlbumFolder(@"disc1"));
Assert.True(IsMultiDiscAlbumFolder(@"disk1"));
// Add a space
Assert.True(IsMultiDiscAlbumFolder(@"cd 1"));
Assert.True(IsMultiDiscAlbumFolder(@"disc 1"));
Assert.True(IsMultiDiscAlbumFolder(@"disk 1"));
Assert.True(IsMultiDiscAlbumFolder(@"cd - 1"));
Assert.True(IsMultiDiscAlbumFolder(@"disc- 1"));
Assert.True(IsMultiDiscAlbumFolder(@"disk - 1"));
Assert.True(IsMultiDiscAlbumFolder(@"Disc 01 (Hugo Wolf · 24 Lieder)"));
Assert.True(IsMultiDiscAlbumFolder(@"Disc 04 (Encores and Folk Songs)"));
Assert.True(IsMultiDiscAlbumFolder(@"Disc04 (Encores and Folk Songs)"));
Assert.True(IsMultiDiscAlbumFolder(@"Disc 04(Encores and Folk Songs)"));
Assert.True(IsMultiDiscAlbumFolder(@"Disc04(Encores and Folk Songs)"));
Assert.True(IsMultiDiscAlbumFolder(@"D:/Video/MBTestLibrary/VideoTest/music/.38 special/anth/Disc 2"));
}
[Fact]
public void TestMultiDiscAlbums1()
{
Assert.False(IsMultiDiscAlbumFolder(@"[1985] Oppurtunities (Let's make lots of money) (1985)"));
}
[Fact]
public void TestMultiDiscAlbums2()
{
Assert.False(IsMultiDiscAlbumFolder(@"Blah 04(Encores and Folk Songs)"));
}
private bool IsMultiDiscAlbumFolder(string path)
{
var parser = new AlbumParser(new NamingOptions());
return parser.ParseMultiPart(path).IsMultiPart;
}
}
}

@ -0,0 +1,40 @@
using Emby.Naming.Common;
using Emby.Naming.Subtitles;
using Xunit;
namespace Jellyfin.Naming.Tests.Subtitles
{
public class SubtitleParserTests
{
private SubtitleParser GetParser()
{
var options = new NamingOptions();
return new SubtitleParser(options);
}
[Fact]
public void TestSubtitles()
{
Test("The Skin I Live In (2011).srt", null, false, false);
Test("The Skin I Live In (2011).eng.srt", "eng", false, false);
Test("The Skin I Live In (2011).eng.default.srt", "eng", true, false);
Test("The Skin I Live In (2011).eng.forced.srt", "eng", false, true);
Test("The Skin I Live In (2011).eng.foreign.srt", "eng", false, true);
Test("The Skin I Live In (2011).eng.default.foreign.srt", "eng", true, true);
Test("The Skin I Live In (2011).default.foreign.eng.srt", "eng", true, true);
}
private void Test(string input, string language, bool isDefault, bool isForced)
{
var parser = GetParser();
var result = parser.ParseFile(input);
Assert.Equal(language, result.Language, true);
Assert.Equal(isDefault, result.IsDefault);
Assert.Equal(isForced, result.IsForced);
}
}
}

@ -0,0 +1,61 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class AbsoluteEpisodeNumberTests
{
[Fact]
public void TestAbsoluteEpisodeNumber1()
{
Assert.Equal(12, GetEpisodeNumberFromFile(@"The Simpsons/12.avi"));
}
[Fact]
public void TestAbsoluteEpisodeNumber2()
{
Assert.Equal(12, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 12.avi"));
}
[Fact]
public void TestAbsoluteEpisodeNumber3()
{
Assert.Equal(82, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 82.avi"));
}
[Fact]
public void TestAbsoluteEpisodeNumber4()
{
Assert.Equal(112, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 112.avi"));
}
[Fact]
public void TestAbsoluteEpisodeNumber5()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/Foo_ep_02.avi"));
}
[Fact]
public void TestAbsoluteEpisodeNumber6()
{
Assert.Equal(889, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 889.avi"));
}
[Fact]
public void TestAbsoluteEpisodeNumber7()
{
Assert.Equal(101, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 101.avi"));
}
private int? GetEpisodeNumberFromFile(string path)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false, null, null, true);
return result.EpisodeNumber;
}
}
}

@ -0,0 +1,69 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class DailyEpisodeTests
{
[Fact]
public void TestDailyEpisode1()
{
Test(@"/server/anything_1996.11.14.mp4", "anything", 1996, 11, 14);
}
[Fact]
public void TestDailyEpisode2()
{
Test(@"/server/anything_1996-11-14.mp4", "anything", 1996, 11, 14);
}
// FIXME
// [Fact]
public void TestDailyEpisode3()
{
Test(@"/server/anything_14.11.1996.mp4", "anything", 1996, 11, 14);
}
// FIXME
// [Fact]
public void TestDailyEpisode4()
{
Test(@"/server/A Daily Show - (2015-01-15) - Episode Name - [720p].mkv", "A Daily Show", 2015, 01, 15);
}
[Fact]
public void TestDailyEpisode5()
{
Test(@"/server/james.corden.2017.04.20.anne.hathaway.720p.hdtv.x264-crooks.mkv", "james.corden", 2017, 04, 20);
}
[Fact]
public void TestDailyEpisode6()
{
Test(@"/server/ABC News 2018_03_24_19_00_00.mkv", "ABC News", 2018, 03, 24);
}
// FIXME
// [Fact]
public void TestDailyEpisode7()
{
Test(@"/server/Last Man Standing_KTLADT_2018_05_25_01_28_00.wtv", "Last Man Standing", 2018, 05, 25);
}
private void Test(string path, string seriesName, int? year, int? month, int? day)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false);
Assert.Null(result.SeasonNumber);
Assert.Null(result.EpisodeNumber);
Assert.Equal(year, result.Year);
Assert.Equal(month, result.Month);
Assert.Equal(day, result.Day);
Assert.Equal(seriesName, result.SeriesName, true);
}
}
}

@ -0,0 +1,421 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class EpisodeNumberTests
{
[Fact]
public void TestEpisodeNumber1()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/S02E03 blah.avi"));
}
[Fact]
public void TestEpisodeNumber40()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2/02x03 - 02x04 - 02x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber41()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/01x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber42()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/S01x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber43()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/S01E02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber44()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2/Elementary - 02x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber45()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/S01xE02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber46()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/seriesname S01E02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber47()
{
Assert.Equal(36, GetEpisodeNumberFromFile(@"Season 2/[HorribleSubs] Hunter X Hunter - 136 [720p].mkv"));
}
[Fact]
public void TestEpisodeNumber50()
{
// This convention is not currently supported, just adding in case we want to look at it in the future
Assert.Equal(1, GetEpisodeNumberFromFile(@"2016/Season s2016e1.mp4"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber51()
{
// This convention is not currently supported, just adding in case we want to look at it in the future
Assert.Equal(1, GetEpisodeNumberFromFile(@"2016/Season 2016x1.mp4"));
}
[Fact]
public void TestEpisodeNumber52()
{
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/Episode - 16.avi"));
}
[Fact]
public void TestEpisodeNumber53()
{
// This is not supported. Expected to fail, although it would be a good one to add support for.
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/Episode 16.avi"));
}
[Fact]
public void TestEpisodeNumber54()
{
// This is not supported. Expected to fail, although it would be a good one to add support for.
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/Episode 16 - Some Title.avi"));
}
[Fact]
public void TestEpisodeNumber55()
{
// This is not supported. Expected to fail, although it would be a good one to add support for.
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/Season 3 Episode 16.avi"));
}
[Fact]
public void TestEpisodeNumber56()
{
// This is not supported. Expected to fail, although it would be a good one to add support for.
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/Season 3 Episode 16 - Some Title.avi"));
}
[Fact]
public void TestEpisodeNumber57()
{
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/16 Some Title.avi"));
}
[Fact]
public void TestEpisodeNumber58()
{
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/16 - 12 Some Title.avi"));
}
[Fact]
public void TestEpisodeNumber59()
{
Assert.Equal(7, GetEpisodeNumberFromFile(@"Season 2/7 - 12 Angry Men.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber60()
{
Assert.Equal(16, GetEpisodeNumberFromFile(@"Season 2/16 12 Some Title.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber61()
{
Assert.Equal(7, GetEpisodeNumberFromFile(@"Season 2/7 12 Angry Men.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber62()
{
// This is not supported. Expected to fail, although it would be a good one to add support for.
Assert.Equal(3, GetEpisodeNumberFromFile(@"Season 4/Uchuu.Senkan.Yamato.2199.E03.avi"));
}
[Fact]
public void TestEpisodeNumber63()
{
Assert.Equal(3, GetEpisodeNumberFromFile(@"Season 4/Uchuu.Senkan.Yamato.2199.S04E03.avi"));
}
[Fact]
public void TestEpisodeNumber64()
{
Assert.Equal(368, GetEpisodeNumberFromFile(@"Running Man/Running Man S2017E368.mkv"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber65()
{
// Not supported yet
Assert.Equal(7, GetEpisodeNumberFromFile(@"/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv/The.Legend.of.Condor.Heroes.2017.E07.V2.web-dl.1080p.h264.aac-hdctv.mkv"));
}
[Fact]
public void TestEpisodeNumber30()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2/02x03 - 02x04 - 02x15 - Ep Name.mp4"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber31()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/seriesname 01x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber32()
{
Assert.Equal(9, GetEpisodeNumberFromFile(@"Season 25/The Simpsons.S25E09.Steal this episode.mp4"));
}
[Fact]
public void TestEpisodeNumber33()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/seriesname S01x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber34()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2/Elementary - 02x03 - 02x04 - 02x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber35()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/seriesname S01xE02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber36()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/02x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber37()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/Elementary - 02x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber38()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/02x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber39()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/Elementary - 02x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber20()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2/02x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber21()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/02x03-E15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber22()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 02/Elementary - 02x03-E15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber23()
{
Assert.Equal(23, GetEpisodeNumberFromFile(@"Season 1/Elementary - S01E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestEpisodeNumber24()
{
Assert.Equal(23, GetEpisodeNumberFromFile(@"Season 2009/S2009E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestEpisodeNumber25()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/2009x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber26()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/S2009x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber27()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/S2009E02 blah.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumber28()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/seriesname 2009x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber29()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber11()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/2009x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber12()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03-E15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber13()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/S2009xE02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber14()
{
Assert.Equal(23, GetEpisodeNumberFromFile(@"Season 2009/Elementary - S2009E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestEpisodeNumber15()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/seriesname S2009xE02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber16()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/2009x03-E15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber17()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/seriesname S2009E02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber18()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/2009x03 - 2009x04 - 2009x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber19()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/2009x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber2()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2009/seriesname S2009x02 blah.avi"));
}
[Fact]
public void TestEpisodeNumber3()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber4()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber5()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/2009x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber6()
{
Assert.Equal(03, GetEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestEpisodeNumber7()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/02 - blah-02 a.avi"));
}
[Fact]
public void TestEpisodeNumber8()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 1/02 - blah.avi"));
}
[Fact]
public void TestEpisodeNumber9()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2/02 - blah 14 blah.avi"));
}
[Fact]
public void TestEpisodeNumber10()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2/02.avi"));
}
[Fact]
public void TestEpisodeNumber48()
{
Assert.Equal(02, GetEpisodeNumberFromFile(@"Season 2/2. Infestation.avi"));
}
[Fact]
public void TestEpisodeNumber49()
{
Assert.Equal(7, GetEpisodeNumberFromFile(@"The Wonder Years/The.Wonder.Years.S04.PDTV.x264-JCH/The Wonder Years s04e07 Christmas Party NTSC PDTV.avi"));
}
private int? GetEpisodeNumberFromFile(string path)
{
var options = new NamingOptions();
var result = new EpisodePathParser(options)
.Parse(path, false);
return result.EpisodeNumber;
}
}
}

@ -0,0 +1,127 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class EpisodeNumberWithoutSeasonTests
{
[Fact]
public void TestEpisodeNumberWithoutSeason1()
{
Assert.Equal(8, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons.S25E08.Steal this episode.mp4"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason2()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons - 02 - Ep Name.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason3()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/02.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason4()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/02 - Ep Name.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason5()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/02-Ep Name.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason6()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/02.EpName.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason7()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons - 02.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason8()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons - 02 Ep Name.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumberWithoutSeason9()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 5 - 02 - Ep Name.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumberWithoutSeason10()
{
Assert.Equal(2, GetEpisodeNumberFromFile(@"The Simpsons/The Simpsons 5 - 02 Ep Name.avi"));
}
// FIXME
// [Fact]
public void TestEpisodeNumberWithoutSeason11()
{
Assert.Equal(7, GetEpisodeNumberFromFile(@"Seinfeld/Seinfeld 0807 The Checks.avi"));
Assert.Equal(8, GetSeasonNumberFromFile(@"Seinfeld/Seinfeld 0807 The Checks.avi"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason12()
{
Assert.Equal(7, GetEpisodeNumberFromFile(@"GJ Club (2013)/GJ Club - 07.mkv"));
}
// FIXME
// [Fact]
public void TestEpisodeNumberWithoutSeason13()
{
// This is not supported anymore after removing the episode number 365+ hack from EpisodePathParser
Assert.Equal(13, GetEpisodeNumberFromFile(@"Case Closed (1996-2007)/Case Closed - 13.mkv"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason14()
{
Assert.Equal(3, GetSeasonNumberFromFile(@"Case Closed (1996-2007)/Case Closed - 317.mkv"));
Assert.Equal(17, GetEpisodeNumberFromFile(@"Case Closed (1996-2007)/Case Closed - 317.mkv"));
}
[Fact]
public void TestEpisodeNumberWithoutSeason15()
{
Assert.Equal(2017, GetSeasonNumberFromFile(@"Running Man/Running Man S2017E368.mkv"));
}
private int? GetEpisodeNumberFromFile(string path)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false);
return result.EpisodeNumber;
}
private int? GetSeasonNumberFromFile(string path)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false);
return result.SeasonNumber;
}
}
}

@ -2,7 +2,7 @@ using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests
namespace Jellyfin.Naming.Tests.TV
{
public class EpisodePathParserTest
{
@ -23,7 +23,7 @@ namespace Jellyfin.Naming.Tests
Assert.Equal(episode, res.EpisodeNumber);
// testing other paths delimeter
var res2 = p.Parse(path.Replace('/', '\\'), false);
var res2 = p.Parse(path.Replace('/', '/'), false);
Assert.True(res2.Success);
Assert.Equal(name, res2.SeriesName);
Assert.Equal(season, res2.SeasonNumber);
@ -45,7 +45,7 @@ namespace Jellyfin.Naming.Tests
Assert.Equal(episode, res.EpisodeNumber);
// testing other paths delimeter
var res2 = p.Parse(path.Replace('/', '\\'), false, fillExtendedInfo: false);
var res2 = p.Parse(path.Replace('/', '/'), false, fillExtendedInfo: false);
Assert.True(res2.Success);
Assert.Equal(name, res2.SeriesName);
Assert.Null(res2.SeasonNumber);

@ -0,0 +1,56 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class EpisodeWithoutSeasonTests
{
// FIXME
// [Fact]
public void TestWithoutSeason1()
{
Test(@"/server/anything_ep02.mp4", "anything", null, 2);
}
// FIXME
// [Fact]
public void TestWithoutSeason2()
{
Test(@"/server/anything_ep_02.mp4", "anything", null, 2);
}
// FIXME
// [Fact]
public void TestWithoutSeason3()
{
Test(@"/server/anything_part.II.mp4", "anything", null, null);
}
// FIXME
// [Fact]
public void TestWithoutSeason4()
{
Test(@"/server/anything_pt.II.mp4", "anything", null, null);
}
// FIXME
// [Fact]
public void TestWithoutSeason5()
{
Test(@"/server/anything_pt_II.mp4", "anything", null, null);
}
private void Test(string path, string seriesName, int? seasonNumber, int? episodeNumber)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false);
Assert.Equal(seasonNumber, result.SeasonNumber);
Assert.Equal(episodeNumber, result.EpisodeNumber);
Assert.Equal(seriesName, result.SeriesName, true);
}
}
}

@ -0,0 +1,105 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class MultiEpisodeTests
{
[Fact]
public void TestGetEndingEpisodeNumberFromFile()
{
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/4x01 20 Hours in America (1).mkv"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/01x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/S01x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/S01E02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/S01xE02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/seriesname 01x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/seriesname S01x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/seriesname S01E02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/seriesname S01xE02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2/02x03 - 04 Ep Name.mp4"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2/My show name 02x03 - 04 Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2/Elementary - 02x03 - 02x04 - 02x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2/02x03 - 02x04 - 02x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2/02x03-04-15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2/Elementary - 02x03-04-15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 02/02x03-E15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 02/Elementary - 02x03-E15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 02/02x03 - x04 - x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 02/Elementary - 02x03 - x04 - x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 02/02x03x04x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 02/Elementary - 02x03x04x15 - Ep Name.mp4"));
Assert.Equal(26, GetEndingEpisodeNumberFromFile(@"Season 1/Elementary - S01E23-E24-E26 - The Woman.mp4"));
Assert.Equal(26, GetEndingEpisodeNumberFromFile(@"Season 1/S01E23-E24-E26 - The Woman.mp4"));
// Four Digits seasons
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/2009x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/S2009x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/S2009E02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/S2009xE02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/seriesname 2009x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/seriesname S2009x02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/seriesname S2009E02 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2009/seriesname S2009xE02 blah.avi"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/2009x03 - 2009x04 - 2009x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/2009x03-04-15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03-04-15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/2009x03-E15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03-E15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/2009x03 - x04 - x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03 - x04 - x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/2009x03x04x15 - Ep Name.mp4"));
Assert.Equal(15, GetEndingEpisodeNumberFromFile(@"Season 2009/Elementary - 2009x03x04x15 - Ep Name.mp4"));
Assert.Equal(26, GetEndingEpisodeNumberFromFile(@"Season 2009/Elementary - S2009E23-E24-E26 - The Woman.mp4"));
Assert.Equal(26, GetEndingEpisodeNumberFromFile(@"Season 2009/S2009E23-E24-E26 - The Woman.mp4"));
// Without season number
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/02 - blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2/02 - blah 14 blah.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/02 - blah-02 a.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2/02.avi"));
Assert.Equal(3, GetEndingEpisodeNumberFromFile(@"Season 1/02-03 - blah.avi"));
Assert.Equal(4, GetEndingEpisodeNumberFromFile(@"Season 2/02-04 - blah 14 blah.avi"));
Assert.Equal(5, GetEndingEpisodeNumberFromFile(@"Season 1/02-05 - blah-02 a.avi"));
Assert.Equal(4, GetEndingEpisodeNumberFromFile(@"Season 2/02-04.avi"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 2/[HorribleSubs] Hunter X Hunter - 136 [720p].mkv"));
// With format specification that must not be detected as ending episode number
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/series-s09e14-1080p.mkv"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/series-s09e14-720p.mkv"));
Assert.Null(GetEndingEpisodeNumberFromFile(@"Season 1/series-s09e14-720i.mkv"));
Assert.Equal(4, GetEndingEpisodeNumberFromFile(@"Season 1/MOONLIGHTING_s01e01-e04.mkv"));
}
[Fact]
public void TestGetEndingEpisodeNumberFromFolder()
{
Assert.Equal(4, GetEndingEpisodeNumberFromFolder(@"Season 1/MOONLIGHTING_s01e01-e04"));
}
private int? GetEndingEpisodeNumberFromFolder(string path)
{
var options = new NamingOptions();
var result = new EpisodePathParser(options)
.Parse(path, true);
return result.EndingEpsiodeNumber;
}
private int? GetEndingEpisodeNumberFromFile(string path)
{
var options = new NamingOptions();
var result = new EpisodePathParser(options)
.Parse(path, false);
return result.EndingEpsiodeNumber;
}
}
}

@ -0,0 +1,112 @@
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class SeasonFolderTests
{
[Fact]
public void TestGetSeasonNumberFromPath1()
{
Assert.Equal(1, GetSeasonNumberFromPath(@"/Drive/Season 1"));
}
[Fact]
public void TestGetSeasonNumberFromPath2()
{
Assert.Equal(2, GetSeasonNumberFromPath(@"/Drive/Season 2"));
}
[Fact]
public void TestGetSeasonNumberFromPath3()
{
Assert.Equal(2, GetSeasonNumberFromPath(@"/Drive/Season 02"));
}
[Fact]
public void TestGetSeasonNumberFromPath4()
{
Assert.Equal(1, GetSeasonNumberFromPath(@"/Drive/Season 1"));
}
[Fact]
public void TestGetSeasonNumberFromPath5()
{
Assert.Equal(2, GetSeasonNumberFromPath(@"/Drive/Seinfeld/S02"));
}
[Fact]
public void TestGetSeasonNumberFromPath6()
{
Assert.Equal(2, GetSeasonNumberFromPath(@"/Drive/Seinfeld/2"));
}
[Fact]
public void TestGetSeasonNumberFromPath7()
{
Assert.Equal(2009, GetSeasonNumberFromPath(@"/Drive/Season 2009"));
}
[Fact]
public void TestGetSeasonNumberFromPath8()
{
Assert.Equal(1, GetSeasonNumberFromPath(@"/Drive/Season1"));
}
[Fact]
public void TestGetSeasonNumberFromPath9()
{
Assert.Equal(4, GetSeasonNumberFromPath(@"The Wonder Years/The.Wonder.Years.S04.PDTV.x264-JCH"));
}
[Fact]
public void TestGetSeasonNumberFromPath10()
{
Assert.Equal(7, GetSeasonNumberFromPath(@"/Drive/Season 7 (2016)"));
}
[Fact]
public void TestGetSeasonNumberFromPath11()
{
Assert.Equal(7, GetSeasonNumberFromPath(@"/Drive/Staffel 7 (2016)"));
}
[Fact]
public void TestGetSeasonNumberFromPath12()
{
Assert.Equal(7, GetSeasonNumberFromPath(@"/Drive/Stagione 7 (2016)"));
}
[Fact]
public void TestGetSeasonNumberFromPath14()
{
Assert.Null(GetSeasonNumberFromPath(@"/Drive/Season (8)"));
}
[Fact]
public void TestGetSeasonNumberFromPath13()
{
Assert.Equal(3, GetSeasonNumberFromPath(@"/Drive/3.Staffel"));
}
[Fact]
public void TestGetSeasonNumberFromPath15()
{
Assert.Null(GetSeasonNumberFromPath(@"/Drive/s06e05"));
}
[Fact]
public void TestGetSeasonNumberFromPath16()
{
Assert.Null(GetSeasonNumberFromPath(@"/Drive/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv"));
}
private int? GetSeasonNumberFromPath(string path)
{
var result = new SeasonPathParser()
.Parse(path, true, true);
return result.SeasonNumber;
}
}
}

@ -0,0 +1,305 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class SeasonNumberTests
{
private int? GetSeasonNumberFromEpisodeFile(string path)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false);
return result.SeasonNumber;
}
[Fact]
public void TestSeasonNumber1()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"/Show/Season 02/S02E03 blah.avi"));
}
[Fact]
public void TestSeasonNumber2()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/seriesname S01x02 blah.avi"));
}
[Fact]
public void TestSeasonNumber3()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/S01x02 blah.avi"));
}
[Fact]
public void TestSeasonNumber4()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/seriesname S01xE02 blah.avi"));
}
[Fact]
public void TestSeasonNumber5()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/01x02 blah.avi"));
}
[Fact]
public void TestSeasonNumber6()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/S01E02 blah.avi"));
}
[Fact]
public void TestSeasonNumber7()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/S01xE02 blah.avi"));
}
// FIXME
// [Fact]
public void TestSeasonNumber8()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/seriesname 01x02 blah.avi"));
}
[Fact]
public void TestSeasonNumber9()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/seriesname S01x02 blah.avi"));
}
[Fact]
public void TestSeasonNumber10()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/seriesname S01E02 blah.avi"));
}
[Fact]
public void TestSeasonNumber11()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 2/Elementary - 02x03 - 02x04 - 02x15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber12()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 2/02x03 - 02x04 - 02x15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber13()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 2/02x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber14()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 2/Elementary - 02x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber15()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 02/02x03-E15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber16()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 02/Elementary - 02x03-E15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber17()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 02/02x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber18()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 02/Elementary - 02x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber19()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 02/02x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber20()
{
Assert.Equal(2, GetSeasonNumberFromEpisodeFile(@"Season 02/Elementary - 02x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestSeasonNumber21()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/Elementary - S01E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestSeasonNumber22()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Season 1/S01E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestSeasonNumber23()
{
Assert.Equal(25, GetSeasonNumberFromEpisodeFile(@"Season 25/The Simpsons.S25E09.Steal this episode.mp4"));
}
[Fact]
public void TestSeasonNumber24()
{
Assert.Equal(25, GetSeasonNumberFromEpisodeFile(@"The Simpsons/The Simpsons.S25E09.Steal this episode.mp4"));
}
[Fact]
public void TestSeasonNumber25()
{
Assert.Equal(2016, GetSeasonNumberFromEpisodeFile(@"2016/Season s2016e1.mp4"));
}
// FIXME
// [Fact]
public void TestSeasonNumber26()
{
// This convention is not currently supported, just adding in case we want to look at it in the future
Assert.Equal(2016, GetSeasonNumberFromEpisodeFile(@"2016/Season 2016x1.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber1()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/2009x02 blah.avi"));
}
[Fact]
public void TestFourDigitSeasonNumber2()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/S2009x02 blah.avi"));
}
[Fact]
public void TestFourDigitSeasonNumber3()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/S2009E02 blah.avi"));
}
[Fact]
public void TestFourDigitSeasonNumber4()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/S2009xE02 blah.avi"));
}
// FIXME
// [Fact]
public void TestFourDigitSeasonNumber5()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/seriesname 2009x02 blah.avi"));
}
[Fact]
public void TestFourDigitSeasonNumber6()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/seriesname S2009x02 blah.avi"));
}
[Fact]
public void TestFourDigitSeasonNumber7()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/seriesname S2009E02 blah.avi"));
}
[Fact]
public void TestFourDigitSeasonNumber8()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber9()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/2009x03 - 2009x04 - 2009x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber10()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/2009x03-04-15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber11()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - 2009x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber12()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/2009x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber13()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - 2009x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber14()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - S2009E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber15()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/S2009E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber16()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - 2009x03 - x04 - x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber17()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/2009x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber18()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - 2009x03x04x15 - Ep Name.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber19()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/Elementary - S2009E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestFourDigitSeasonNumber20()
{
Assert.Equal(2009, GetSeasonNumberFromEpisodeFile(@"Season 2009/S2009E23-E24-E26 - The Woman.mp4"));
}
[Fact]
public void TestNoSeriesFolder()
{
Assert.Equal(1, GetSeasonNumberFromEpisodeFile(@"Series/1-12 - The Woman.mp4"));
}
}
}

@ -0,0 +1,95 @@
using Emby.Naming.Common;
using Emby.Naming.TV;
using Xunit;
namespace Jellyfin.Naming.Tests.TV
{
public class SimpleEpisodeTests
{
[Fact]
public void TestSimpleEpisodePath1()
{
Test(@"/server/anything_s01e02.mp4", "anything", 1, 2);
}
[Fact]
public void TestSimpleEpisodePath2()
{
Test(@"/server/anything_s1e2.mp4", "anything", 1, 2);
}
[Fact]
public void TestSimpleEpisodePath3()
{
Test(@"/server/anything_s01.e02.mp4", "anything", 1, 2);
}
[Fact]
public void TestSimpleEpisodePath4()
{
Test(@"/server/anything_s01_e02.mp4", "anything", 1, 2);
}
[Fact]
public void TestSimpleEpisodePath5()
{
Test(@"/server/anything_102.mp4", "anything", 1, 2);
}
[Fact]
public void TestSimpleEpisodePath6()
{
Test(@"/server/anything_1x02.mp4", "anything", 1, 2);
}
// FIXME
// [Fact]
public void TestSimpleEpisodePath7()
{
Test(@"/server/The Walking Dead 4x01.mp4", "The Walking Dead", 4, 1);
}
[Fact]
public void TestSimpleEpisodePath8()
{
Test(@"/server/the_simpsons-s02e01_18536.mp4", "the_simpsons", 2, 1);
}
[Fact]
public void TestSimpleEpisodePath9()
{
Test(@"/server/Temp/S01E02 foo.mp4", string.Empty, 1, 2);
}
[Fact]
public void TestSimpleEpisodePath10()
{
Test(@"Series/4-12 - The Woman.mp4", string.Empty, 4, 12);
}
[Fact]
public void TestSimpleEpisodePath11()
{
Test(@"Series/4x12 - The Woman.mp4", string.Empty, 4, 12);
}
[Fact]
public void TestSimpleEpisodePath12()
{
Test(@"Series/LA X, Pt. 1_s06e32.mp4", "LA X, Pt. 1", 6, 32);
}
private void Test(string path, string seriesName, int? seasonNumber, int? episodeNumber)
{
var options = new NamingOptions();
var result = new EpisodeResolver(options)
.Resolve(path, false);
Assert.Equal(seasonNumber, result.SeasonNumber);
Assert.Equal(episodeNumber, result.EpisodeNumber);
Assert.Equal(seriesName, result.SeriesName, true);
}
}
}

@ -0,0 +1,15 @@
using Emby.Naming.Common;
using Emby.Naming.Video;
namespace Jellyfin.Naming.Tests.Video
{
public abstract class BaseVideoTest
{
protected VideoResolver GetParser()
{
var options = new NamingOptions();
return new VideoResolver(options);
}
}
}

@ -0,0 +1,143 @@
using System.IO;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class CleanDateTimeTests : BaseVideoTest
{
// FIXME
// [Fact]
public void TestCleanDateTime()
{
Test(@"The Wolf of Wall Street (2013).mkv", "The Wolf of Wall Street", 2013);
Test(@"The Wolf of Wall Street 2 (2013).mkv", "The Wolf of Wall Street 2", 2013);
Test(@"The Wolf of Wall Street - 2 (2013).mkv", "The Wolf of Wall Street - 2", 2013);
Test(@"The Wolf of Wall Street 2001 (2013).mkv", "The Wolf of Wall Street 2001", 2013);
Test(@"300 (2006).mkv", "300", 2006);
Test(@"d:/movies/300 (2006).mkv", "300", 2006);
Test(@"300 2 (2006).mkv", "300 2", 2006);
Test(@"300 - 2 (2006).mkv", "300 - 2", 2006);
Test(@"300 2001 (2006).mkv", "300 2001", 2006);
Test(@"curse.of.chucky.2013.stv.unrated.multi.1080p.bluray.x264-rough", "curse.of.chucky", 2013);
Test(@"curse.of.chucky.2013.stv.unrated.multi.2160p.bluray.x264-rough", "curse.of.chucky", 2013);
Test(@"/server/Movies/300 (2007)/300 (2006).bluray.disc", "300", 2006);
}
// FIXME
// [Fact]
public void TestCleanDateTime1()
{
Test(@"Arrival.2016.2160p.Blu-Ray.HEVC.mkv", "Arrival", 2016);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithoutFileExtension()
{
Test(@"The Wolf of Wall Street (2013)", "The Wolf of Wall Street", 2013);
Test(@"The Wolf of Wall Street 2 (2013)", "The Wolf of Wall Street 2", 2013);
Test(@"The Wolf of Wall Street - 2 (2013)", "The Wolf of Wall Street - 2", 2013);
Test(@"The Wolf of Wall Street 2001 (2013)", "The Wolf of Wall Street 2001", 2013);
Test(@"300 (2006)", "300", 2006);
Test(@"d:/movies/300 (2006)", "300", 2006);
Test(@"300 2 (2006)", "300 2", 2006);
Test(@"300 - 2 (2006)", "300 - 2", 2006);
Test(@"300 2001 (2006)", "300 2001", 2006);
Test(@"/server/Movies/300 (2007)/300 (2006)", "300", 2006);
Test(@"/server/Movies/300 (2007)/300 (2006).mkv", "300", 2006);
}
[Fact]
public void TestCleanDateTimeWithoutDate()
{
Test(@"American.Psycho.mkv", "American.Psycho.mkv", null);
Test(@"American Psycho.mkv", "American Psycho.mkv", null);
}
[Fact]
public void TestCleanDateTimeWithBracketedName()
{
Test(@"[rec].mkv", "[rec].mkv", null);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithoutExtension()
{
Test(@"St. Vincent (2014)", "St. Vincent", 2014);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithoutDate1()
{
Test("Super movie(2009).mp4", "Super movie", 2009);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithoutParenthesis()
{
Test("Drug War 2013.mp4", "Drug War", 2013);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithMultipleYears()
{
Test("My Movie (1997) - GreatestReleaseGroup 2019.mp4", "My Movie", 1997);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithYearAndResolution()
{
Test("First Man 2018 1080p.mkv", "First Man", 2018);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithYearAndResolution1()
{
Test("First Man (2018) 1080p.mkv", "First Man", 2018);
}
// FIXME
// [Fact]
public void TestCleanDateTimeWithSceneRelease()
{
Test("Maximum Ride - 2016 - WEBDL-1080p - x264 AC3.mkv", "Maximum Ride", 2016);
}
// FIXME
// [Fact]
public void TestYearInBrackets()
{
Test("Robin Hood [Multi-Subs] [2018].mkv", "Robin Hood", 2018);
}
private void Test(string input, string expectedName, int? expectedYear)
{
input = Path.GetFileName(input);
var result = GetParser().CleanDateTime(input);
Assert.Equal(expectedName, result.Name, true);
Assert.Equal(expectedYear, result.Year);
}
// FIXME
// [Fact]
public void TestCleanDateAndStringsSequence()
{
// In this test case, running CleanDateTime first produces no date, so it will attempt to run CleanString first and then CleanDateTime again
Test(@"3.Days.to.Kill.2014.720p.BluRay.x264.YIFY.mkv", "3.Days.to.Kill", 2014);
}
}
}

@ -0,0 +1,133 @@
using System;
using System.Globalization;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class CleanStringTests : BaseVideoTest
{
// FIXME
// [Fact]
public void TestCleanString()
{
Test("Super movie 480p.mp4", "Super movie");
Test("Super movie 480p 2001.mp4", "Super movie");
Test("Super movie [480p].mp4", "Super movie");
Test("480 Super movie [tmdbid=12345].mp4", "480 Super movie");
}
// FIXME
// [Fact]
public void TestCleanString1()
{
Test("Super movie(2009).mp4", "Super movie(2009).mp4");
}
// FIXME
// [Fact]
public void TestCleanString2()
{
Test("Run lola run (lola rennt) (2009).mp4", "Run lola run (lola rennt) (2009).mp4");
}
// FIXME
// [Fact]
public void TestStringWithoutDate()
{
Test(@"American.Psycho.mkv", "American.Psycho.mkv");
Test(@"American Psycho.mkv", "American Psycho.mkv");
}
// FIXME
// [Fact]
public void TestNameWithBrackets()
{
Test(@"[rec].mkv", "[rec].mkv");
}
// FIXME
// [Fact]
public void Test4k()
{
Test("Crouching.Tiger.Hidden.Dragon.4k.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestUltraHd()
{
Test("Crouching.Tiger.Hidden.Dragon.UltraHD.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestUHd()
{
Test("Crouching.Tiger.Hidden.Dragon.UHD.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestHDR()
{
Test("Crouching.Tiger.Hidden.Dragon.HDR.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestHDC()
{
Test("Crouching.Tiger.Hidden.Dragon.HDC.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestHDC1()
{
Test("Crouching.Tiger.Hidden.Dragon-HDC.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestBDrip()
{
Test("Crouching.Tiger.Hidden.Dragon.BDrip.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestBDripHDC()
{
Test("Crouching.Tiger.Hidden.Dragon.BDrip-HDC.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestMulti()
{
Test("Crouching.Tiger.Hidden.Dragon.4K.UltraHD.HDR.BDrip-HDC.mkv", "Crouching.Tiger.Hidden.Dragon");
}
// FIXME
// [Fact]
public void TestLeadingBraces()
{
// Not actually supported, just reported by a user
Test("[0004] - After The Sunset.el.mkv", "After The Sunset");
}
// FIXME
// [Fact]
public void TestTrailingBraces()
{
Test("After The Sunset - [0004].mkv", "After The Sunset");
}
private void Test(string input, string expectedName)
{
var result = GetParser().CleanString(input).ToString();
Assert.Equal(expectedName, result, true);
}
}
}

@ -0,0 +1,77 @@
using Emby.Naming.Common;
using Emby.Naming.Video;
using MediaBrowser.Model.Entities;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class ExtraTests : BaseVideoTest
{
// Requirements
// movie-deleted = ExtraType deletedscene
// All of the above rules should be configurable through the options objects (ideally, even the ExtraTypes)
[Fact]
public void TestKodiExtras()
{
var videoOptions = new NamingOptions();
Test("trailer.mp4", ExtraType.Trailer, videoOptions);
Test("300-trailer.mp4", ExtraType.Trailer, videoOptions);
Test("theme.mp3", ExtraType.ThemeSong, videoOptions);
}
[Fact]
public void TestExpandedExtras()
{
var videoOptions = new NamingOptions();
Test("trailer.mp4", ExtraType.Trailer, videoOptions);
Test("trailer.mp3", null, videoOptions);
Test("300-trailer.mp4", ExtraType.Trailer, videoOptions);
Test("theme.mp3", ExtraType.ThemeSong, videoOptions);
Test("theme.mkv", null, videoOptions);
Test("300-scene.mp4", ExtraType.Scene, videoOptions);
Test("300-scene2.mp4", ExtraType.Scene, videoOptions);
Test("300-clip.mp4", ExtraType.Clip, videoOptions);
Test("300-deleted.mp4", ExtraType.DeletedScene, videoOptions);
Test("300-deletedscene.mp4", ExtraType.DeletedScene, videoOptions);
Test("300-interview.mp4", ExtraType.Interview, videoOptions);
Test("300-behindthescenes.mp4", ExtraType.BehindTheScenes, videoOptions);
}
[Fact]
public void TestSample()
{
var videoOptions = new NamingOptions();
Test("300-sample.mp4", ExtraType.Sample, videoOptions);
}
private void Test(string input, ExtraType? expectedType, NamingOptions videoOptions)
{
var parser = GetExtraTypeParser(videoOptions);
var extraType = parser.GetExtraInfo(input).ExtraType;
if (expectedType == null)
{
Assert.Null(extraType);
}
else
{
Assert.Equal(expectedType, extraType);
}
}
private ExtraResolver GetExtraTypeParser(NamingOptions videoOptions)
{
return new ExtraResolver(videoOptions);
}
}
}

@ -0,0 +1,78 @@
using Emby.Naming.Common;
using Emby.Naming.Video;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class Format3DTests : BaseVideoTest
{
[Fact]
public void TestKodiFormat3D()
{
var options = new NamingOptions();
Test("Super movie.3d.mp4", false, null, options);
Test("Super movie.3d.hsbs.mp4", true, "hsbs", options);
Test("Super movie.3d.sbs.mp4", true, "sbs", options);
Test("Super movie.3d.htab.mp4", true, "htab", options);
Test("Super movie.3d.tab.mp4", true, "tab", options);
Test("Super movie 3d hsbs.mp4", true, "hsbs", options);
}
[Fact]
public void Test3DName()
{
var result =
GetParser().ResolveFile(@"C:/Users/media/Desktop/Video Test/Movies/Oblivion/Oblivion.3d.hsbs.mkv");
Assert.Equal("hsbs", result.Format3D);
Assert.Equal("Oblivion", result.Name);
}
[Fact]
public void TestExpandedFormat3D()
{
// These were introduced for Media Browser 3
// Kodi conventions are preferred but these still need to be supported
var options = new NamingOptions();
Test("Super movie.3d.mp4", false, null, options);
Test("Super movie.3d.hsbs.mp4", true, "hsbs", options);
Test("Super movie.3d.sbs.mp4", true, "sbs", options);
Test("Super movie.3d.htab.mp4", true, "htab", options);
Test("Super movie.3d.tab.mp4", true, "tab", options);
Test("Super movie.hsbs.mp4", true, "hsbs", options);
Test("Super movie.sbs.mp4", true, "sbs", options);
Test("Super movie.htab.mp4", true, "htab", options);
Test("Super movie.tab.mp4", true, "tab", options);
Test("Super movie.sbs3d.mp4", true, "sbs3d", options);
Test("Super movie.3d.mvc.mp4", true, "mvc", options);
Test("Super movie [3d].mp4", false, null, options);
Test("Super movie [hsbs].mp4", true, "hsbs", options);
Test("Super movie [fsbs].mp4", true, "fsbs", options);
Test("Super movie [ftab].mp4", true, "ftab", options);
Test("Super movie [htab].mp4", true, "htab", options);
Test("Super movie [sbs3d].mp4", true, "sbs3d", options);
}
private void Test(string input, bool is3D, string format3D, NamingOptions options)
{
var parser = new Format3DParser(options);
var result = parser.Parse(input);
Assert.Equal(is3D, result.Is3D);
if (format3D == null)
{
Assert.Null(result.Format3D);
}
else
{
Assert.Equal(format3D, result.Format3D, true);
}
}
}
}

@ -0,0 +1,438 @@
using System.Linq;
using Emby.Naming.Common;
using Emby.Naming.Video;
using MediaBrowser.Model.IO;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class MultiVersionTests
{
// FIXME
// [Fact]
public void TestMultiEdition1()
{
var files = new[]
{
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past - 1080p.mkv",
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past-trailer.mp4",
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past - [hsbs].mkv",
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past [hsbs].mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Single(result[0].Extras);
}
// FIXME
// [Fact]
public void TestMultiEdition2()
{
var files = new[]
{
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past - apple.mkv",
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past-trailer.mp4",
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past - banana.mkv",
@"/movies/X-Men Days of Future Past/X-Men Days of Future Past [banana].mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Single(result[0].Extras);
Assert.Equal(2, result[0].AlternateVersions.Count);
}
[Fact]
public void TestMultiEdition3()
{
// This is currently not supported and will fail, but we should try to figure it out
var files = new[]
{
@"/movies/The Phantom of the Opera (1925)/The Phantom of the Opera (1925) - 1925 version.mkv",
@"/movies/The Phantom of the Opera (1925)/The Phantom of the Opera (1925) - 1929 version.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Single(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestLetterFolders()
{
var files = new[]
{
@"/movies/M/Movie 1.mkv",
@"/movies/M/Movie 2.mkv",
@"/movies/M/Movie 3.mkv",
@"/movies/M/Movie 4.mkv",
@"/movies/M/Movie 5.mkv",
@"/movies/M/Movie 6.mkv",
@"/movies/M/Movie 7.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(7, result.Count);
Assert.Empty(result[0].Extras);
Assert.Empty(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestMultiVersionLimit()
{
var files = new[]
{
@"/movies/Movie/Movie.mkv",
@"/movies/Movie/Movie-2.mkv",
@"/movies/Movie/Movie-3.mkv",
@"/movies/Movie/Movie-4.mkv",
@"/movies/Movie/Movie-5.mkv",
@"/movies/Movie/Movie-6.mkv",
@"/movies/Movie/Movie-7.mkv",
@"/movies/Movie/Movie-8.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Empty(result[0].Extras);
Assert.Equal(7, result[0].AlternateVersions.Count);
}
// FIXME
// [Fact]
public void TestMultiVersionLimit2()
{
var files = new[]
{
@"/movies/Mo/Movie 1.mkv",
@"/movies/Mo/Movie 2.mkv",
@"/movies/Mo/Movie 3.mkv",
@"/movies/Mo/Movie 4.mkv",
@"/movies/Mo/Movie 5.mkv",
@"/movies/Mo/Movie 6.mkv",
@"/movies/Mo/Movie 7.mkv",
@"/movies/Mo/Movie 8.mkv",
@"/movies/Mo/Movie 9.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(9, result.Count);
Assert.Empty(result[0].Extras);
Assert.Empty(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestMultiVersion3()
{
var files = new[]
{
@"/movies/Movie/Movie 1.mkv",
@"/movies/Movie/Movie 2.mkv",
@"/movies/Movie/Movie 3.mkv",
@"/movies/Movie/Movie 4.mkv",
@"/movies/Movie/Movie 5.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(5, result.Count);
Assert.Empty(result[0].Extras);
Assert.Empty(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestMultiVersion4()
{
// Test for false positive
var files = new[]
{
@"/movies/Iron Man/Iron Man.mkv",
@"/movies/Iron Man/Iron Man (2008).mkv",
@"/movies/Iron Man/Iron Man (2009).mkv",
@"/movies/Iron Man/Iron Man (2010).mkv",
@"/movies/Iron Man/Iron Man (2011).mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(5, result.Count);
Assert.Empty(result[0].Extras);
Assert.Empty(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestMultiVersion5()
{
var files = new[]
{
@"/movies/Iron Man/Iron Man.mkv",
@"/movies/Iron Man/Iron Man-720p.mkv",
@"/movies/Iron Man/Iron Man-test.mkv",
@"/movies/Iron Man/Iron Man-bluray.mkv",
@"/movies/Iron Man/Iron Man-3d.mkv",
@"/movies/Iron Man/Iron Man-3d-hsbs.mkv",
@"/movies/Iron Man/Iron Man-3d.hsbs.mkv",
@"/movies/Iron Man/Iron Man[test].mkv",
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Empty(result[0].Extras);
Assert.Equal(7, result[0].AlternateVersions.Count);
Assert.False(result[0].AlternateVersions[2].Is3D);
Assert.True(result[0].AlternateVersions[3].Is3D);
Assert.True(result[0].AlternateVersions[4].Is3D);
}
// FIXME
// [Fact]
public void TestMultiVersion6()
{
var files = new[]
{
@"/movies/Iron Man/Iron Man.mkv",
@"/movies/Iron Man/Iron Man - 720p.mkv",
@"/movies/Iron Man/Iron Man - test.mkv",
@"/movies/Iron Man/Iron Man - bluray.mkv",
@"/movies/Iron Man/Iron Man - 3d.mkv",
@"/movies/Iron Man/Iron Man - 3d-hsbs.mkv",
@"/movies/Iron Man/Iron Man - 3d.hsbs.mkv",
@"/movies/Iron Man/Iron Man [test].mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Empty(result[0].Extras);
Assert.Equal(7, result[0].AlternateVersions.Count);
Assert.False(result[0].AlternateVersions[3].Is3D);
Assert.True(result[0].AlternateVersions[4].Is3D);
Assert.True(result[0].AlternateVersions[5].Is3D);
}
// FIXME
// [Fact]
public void TestMultiVersion7()
{
var files = new[]
{
@"/movies/Iron Man/Iron Man - B (2006).mkv",
@"/movies/Iron Man/Iron Man - C (2007).mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(2, result.Count);
}
// FIXME
// [Fact]
public void TestMultiVersion8()
{
// This is not actually supported yet
var files = new[]
{
@"/movies/Iron Man/Iron Man.mkv",
@"/movies/Iron Man/Iron Man_720p.mkv",
@"/movies/Iron Man/Iron Man_test.mkv",
@"/movies/Iron Man/Iron Man_bluray.mkv",
@"/movies/Iron Man/Iron Man_3d.mkv",
@"/movies/Iron Man/Iron Man_3d-hsbs.mkv",
@"/movies/Iron Man/Iron Man_3d.hsbs.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Empty(result[0].Extras);
Assert.Equal(6, result[0].AlternateVersions.Count);
Assert.False(result[0].AlternateVersions[2].Is3D);
Assert.True(result[0].AlternateVersions[3].Is3D);
Assert.True(result[0].AlternateVersions[4].Is3D);
}
// FIXME
// [Fact]
public void TestMultiVersion9()
{
// Test for false positive
var files = new[]
{
@"/movies/Iron Man/Iron Man (2007).mkv",
@"/movies/Iron Man/Iron Man (2008).mkv",
@"/movies/Iron Man/Iron Man (2009).mkv",
@"/movies/Iron Man/Iron Man (2010).mkv",
@"/movies/Iron Man/Iron Man (2011).mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(5, result.Count);
Assert.Empty(result[0].Extras);
Assert.Empty(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestMultiVersion10()
{
var files = new[]
{
@"/movies/Blade Runner (1982)/Blade Runner (1982) [Final Cut] [1080p HEVC AAC].mkv",
@"/movies/Blade Runner (1982)/Blade Runner (1982) [EE by ADM] [480p HEVC AAC,AAC,AAC].mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Empty(result[0].Extras);
Assert.Single(result[0].AlternateVersions);
}
// FIXME
// [Fact]
public void TestMultiVersion11()
{
// Currently not supported but we should probably handle this.
var files = new[]
{
@"/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016) [1080p] Blu-ray.x264.DTS.mkv",
@"/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016) [2160p] Blu-ray.x265.AAC.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
Assert.Empty(result[0].Extras);
Assert.Single(result[0].AlternateVersions);
}
private VideoListResolver GetResolver()
{
var options = new NamingOptions();
return new VideoListResolver(options);
}
}
}

@ -0,0 +1,478 @@
using Emby.Naming.Common;
using Emby.Naming.Video;
using MediaBrowser.Model.IO;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class StackTests : BaseVideoTest
{
[Fact]
public void TestSimpleStack()
{
var files = new[]
{
"Bad Boys (2006) part1.mkv",
"Bad Boys (2006) part2.mkv",
"Bad Boys (2006) part3.mkv",
"Bad Boys (2006) part4.mkv",
"Bad Boys (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "Bad Boys (2006)", 4);
}
[Fact]
public void TestFalsePositives()
{
var files = new[]
{
"Bad Boys (2006).mkv",
"Bad Boys (2007).mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestFalsePositives2()
{
var files = new[]
{
"Bad Boys 2006.mkv",
"Bad Boys 2007.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestFalsePositives3()
{
var files = new[]
{
"300 (2006).mkv",
"300 (2007).mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestFalsePositives4()
{
var files = new[]
{
"300 2006.mkv",
"300 2007.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestFalsePositives5()
{
var files = new[]
{
"Star Trek 1 - The motion picture.mkv",
"Star Trek 2- The wrath of khan.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestFalsePositives6()
{
var files = new[]
{
"Red Riding in the Year of Our Lord 1983 (2009).mkv",
"Red Riding in the Year of Our Lord 1980 (2009).mkv",
"Red Riding in the Year of Our Lord 1974 (2009).mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestStackName()
{
var files = new[]
{
"d:/movies/300 2006 part1.mkv",
"d:/movies/300 2006 part2.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "300 2006", 2);
}
[Fact]
public void TestDirtyNames()
{
var files = new[]
{
"Bad Boys (2006).part1.stv.unrated.multi.1080p.bluray.x264-rough.mkv",
"Bad Boys (2006).part2.stv.unrated.multi.1080p.bluray.x264-rough.mkv",
"Bad Boys (2006).part3.stv.unrated.multi.1080p.bluray.x264-rough.mkv",
"Bad Boys (2006).part4.stv.unrated.multi.1080p.bluray.x264-rough.mkv",
"Bad Boys (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "Bad Boys (2006).stv.unrated.multi.1080p.bluray.x264-rough", 4);
}
[Fact]
public void TestNumberedFiles()
{
var files = new[]
{
"Bad Boys (2006).mkv",
"Bad Boys (2006) 1.mkv",
"Bad Boys (2006) 2.mkv",
"Bad Boys (2006) 3.mkv",
"Bad Boys (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestSimpleStackWithNumericName()
{
var files = new[]
{
"300 (2006) part1.mkv",
"300 (2006) part2.mkv",
"300 (2006) part3.mkv",
"300 (2006) part4.mkv",
"300 (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "300 (2006)", 4);
}
[Fact]
public void TestMixedExpressionsNotAllowed()
{
var files = new[]
{
"Bad Boys (2006) part1.mkv",
"Bad Boys (2006) part2.mkv",
"Bad Boys (2006) part3.mkv",
"Bad Boys (2006) parta.mkv",
"Bad Boys (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "Bad Boys (2006)", 3);
}
[Fact]
public void TestDualStacks()
{
var files = new[]
{
"Bad Boys (2006) part1.mkv",
"Bad Boys (2006) part2.mkv",
"Bad Boys (2006) part3.mkv",
"Bad Boys (2006) part4.mkv",
"Bad Boys (2006)-trailer.mkv",
"300 (2006) part1.mkv",
"300 (2006) part2.mkv",
"300 (2006) part3.mkv",
"300 (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Equal(2, result.Stacks.Count);
TestStackInfo(result.Stacks[1], "Bad Boys (2006)", 4);
TestStackInfo(result.Stacks[0], "300 (2006)", 3);
}
[Fact]
public void TestDirectories()
{
var files = new[]
{
"blah blah - cd 1",
"blah blah - cd 2"
};
var resolver = GetResolver();
var result = resolver.ResolveDirectories(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "blah blah", 2);
}
[Fact]
public void TestFalsePositive()
{
var files = new[]
{
"300a.mkv",
"300b.mkv",
"300c.mkv",
"300-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "300", 3);
}
[Fact]
public void TestFailSequence()
{
var files = new[]
{
"300 part1.mkv",
"300 part2.mkv",
"Avatar",
"Avengers part1.mkv",
"Avengers part2.mkv",
"Avengers part3.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Equal(2, result.Stacks.Count);
TestStackInfo(result.Stacks[0], "300", 2);
TestStackInfo(result.Stacks[1], "Avengers", 3);
}
[Fact]
public void TestMixedExpressions()
{
var files = new[]
{
"Bad Boys (2006) part1.mkv",
"Bad Boys (2006) part2.mkv",
"Bad Boys (2006) part3.mkv",
"Bad Boys (2006) part4.mkv",
"Bad Boys (2006)-trailer.mkv",
"300 (2006) parta.mkv",
"300 (2006) partb.mkv",
"300 (2006) partc.mkv",
"300 (2006) partd.mkv",
"300 (2006)-trailer.mkv",
"300a.mkv",
"300b.mkv",
"300c.mkv",
"300-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Equal(3, result.Stacks.Count);
TestStackInfo(result.Stacks[0], "300 (2006)", 4);
TestStackInfo(result.Stacks[1], "300", 3);
TestStackInfo(result.Stacks[2], "Bad Boys (2006)", 4);
}
[Fact]
public void TestAlphaLimitOfFour()
{
var files = new[]
{
"300 (2006) parta.mkv",
"300 (2006) partb.mkv",
"300 (2006) partc.mkv",
"300 (2006) partd.mkv",
"300 (2006) parte.mkv",
"300 (2006) partf.mkv",
"300 (2006) partg.mkv",
"300 (2006)-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
TestStackInfo(result.Stacks[0], "300 (2006)", 4);
}
[Fact]
public void TestMixed()
{
var files = new[]
{
new FileSystemMetadata{FullName = "Bad Boys (2006) part1.mkv", IsDirectory = false},
new FileSystemMetadata{FullName = "Bad Boys (2006) part2.mkv", IsDirectory = false},
new FileSystemMetadata{FullName = "300 (2006) part2", IsDirectory = true},
new FileSystemMetadata{FullName = "300 (2006) part3", IsDirectory = true},
new FileSystemMetadata{FullName = "300 (2006) part1", IsDirectory = true}
};
var resolver = GetResolver();
var result = resolver.Resolve(files);
Assert.Equal(2, result.Stacks.Count);
TestStackInfo(result.Stacks[0], "300 (2006)", 3);
TestStackInfo(result.Stacks[1], "Bad Boys (2006)", 2);
}
[Fact]
public void TestDirectories2()
{
//TestDirectory(@"blah blah", false, @"blah blah");
//TestDirectory(@"d:/music/weezer/03 Pinkerton", false, "03 Pinkerton");
//TestDirectory(@"d:/music/michael jackson/Bad (2012 Remaster)", false, "Bad (2012 Remaster)");
//TestDirectory(@"blah blah - cd1", true, "blah blah");
//TestDirectory(@"blah blah - disc1", true, "blah blah");
//TestDirectory(@"blah blah - disk1", true, "blah blah");
//TestDirectory(@"blah blah - pt1", true, "blah blah");
//TestDirectory(@"blah blah - part1", true, "blah blah");
//TestDirectory(@"blah blah - dvd1", true, "blah blah");
//// Add a space
//TestDirectory(@"blah blah - cd 1", true, "blah blah");
//TestDirectory(@"blah blah - disc 1", true, "blah blah");
//TestDirectory(@"blah blah - disk 1", true, "blah blah");
//TestDirectory(@"blah blah - pt 1", true, "blah blah");
//TestDirectory(@"blah blah - part 1", true, "blah blah");
//TestDirectory(@"blah blah - dvd 1", true, "blah blah");
//// Not case sensitive
//TestDirectory(@"blah blah - Disc1", true, "blah blah");
}
[Fact]
public void TestNamesWithoutParts()
{
// No stacking here because there is no part/disc/etc
var files = new[]
{
"Harry Potter and the Deathly Hallows.mkv",
"Harry Potter and the Deathly Hallows 1.mkv",
"Harry Potter and the Deathly Hallows 2.mkv",
"Harry Potter and the Deathly Hallows 3.mkv",
"Harry Potter and the Deathly Hallows 4.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Empty(result.Stacks);
}
[Fact]
public void TestNumbersAppearingBeforePartNumber()
{
// No stacking here because there is no part/disc/etc
var files = new[]
{
"Neverland (2011)[720p][PG][Voted 6.5][Family-Fantasy]part1.mkv",
"Neverland (2011)[720p][PG][Voted 6.5][Family-Fantasy]part2.mkv"
};
var resolver = GetResolver();
var result = resolver.ResolveFiles(files);
Assert.Single(result.Stacks);
Assert.Equal(2, result.Stacks[0].Files.Count);
}
[Fact]
public void TestMultiDiscs()
{
// No stacking here because there is no part/disc/etc
var files = new[]
{
@"M:/Movies (DVD)/Movies (Musical)/The Sound of Music/The Sound of Music (1965) (Disc 01)",
@"M:/Movies (DVD)/Movies (Musical)/The Sound of Music/The Sound of Music (1965) (Disc 02)"
};
var resolver = GetResolver();
var result = resolver.ResolveDirectories(files);
Assert.Single(result.Stacks);
Assert.Equal(2, result.Stacks[0].Files.Count);
}
private void TestStackInfo(FileStack stack, string name, int fileCount)
{
Assert.Equal(fileCount, stack.Files.Count);
Assert.Equal(name, stack.Name);
}
private StackResolver GetResolver()
{
return new StackResolver(new NamingOptions());
}
}
}

@ -0,0 +1,55 @@
using System;
using System.Globalization;
using Emby.Naming.Common;
using Emby.Naming.Video;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class StubTests : BaseVideoTest
{
[Fact]
public void TestStubs()
{
Test("video.mkv", false, null);
Test("video.disc", true, null);
Test("video.dvd.disc", true, "dvd");
Test("video.hddvd.disc", true, "hddvd");
Test("video.bluray.disc", true, "bluray");
Test("video.brrip.disc", true, "bluray");
Test("video.bd25.disc", true, "bluray");
Test("video.bd50.disc", true, "bluray");
Test("video.vhs.disc", true, "vhs");
Test("video.hdtv.disc", true, "tv");
Test("video.pdtv.disc", true, "tv");
Test("video.dsr.disc", true, "tv");
}
[Fact]
public void TestStubName()
{
var result =
GetParser().ResolveFile(@"C:/Users/media/Desktop/Video Test/Movies/Oblivion/Oblivion.dvd.disc");
Assert.Equal("Oblivion", result.Name);
}
private void Test(string path, bool isStub, string stubType)
{
var options = new NamingOptions();
var resultStubType = StubResolver.ResolveFile(path, options);
Assert.Equal(isStub, resultStubType.IsStub);
if (stubType == null)
{
Assert.Null(resultStubType.StubType);
}
else
{
Assert.Equal(stubType, resultStubType.StubType, true);
}
}
}
}

@ -0,0 +1,457 @@
using System.Linq;
using Emby.Naming.Common;
using Emby.Naming.Video;
using MediaBrowser.Model.IO;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class VideoListResolverTests
{
// FIXME
// [Fact]
public void TestStackAndExtras()
{
// No stacking here because there is no part/disc/etc
var files = new[]
{
"Harry Potter and the Deathly Hallows-trailer.mkv",
"Harry Potter and the Deathly Hallows.trailer.mkv",
"Harry Potter and the Deathly Hallows part1.mkv",
"Harry Potter and the Deathly Hallows part2.mkv",
"Harry Potter and the Deathly Hallows part3.mkv",
"Harry Potter and the Deathly Hallows part4.mkv",
"Batman-deleted.mkv",
"Batman-sample.mkv",
"Batman-trailer.mkv",
"Batman part1.mkv",
"Batman part2.mkv",
"Batman part3.mkv",
"Avengers.mkv",
"Avengers-trailer.mkv",
// Despite having a keyword in the name that will return an ExtraType, there's no original video to match it to
// So this is just a standalone video
"trailer.mkv",
// Same as above
"WillyWonka-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(5, result.Count);
Assert.Equal(3, result[1].Files.Count);
Assert.Equal(3, result[1].Extras.Count);
Assert.Equal("Batman", result[1].Name);
Assert.Equal(4, result[2].Files.Count);
Assert.Equal(2, result[2].Extras.Count);
Assert.Equal("Harry Potter and the Deathly Hallows", result[2].Name);
}
[Fact]
public void TestWithMetadata()
{
var files = new[]
{
"300.mkv",
"300.nfo"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestWithExtra()
{
var files = new[]
{
"300.mkv",
"300 trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestVariationWithFolderName()
{
var files = new[]
{
"X-Men Days of Future Past - 1080p.mkv",
"X-Men Days of Future Past-trailer.mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestTrailer2()
{
var files = new[]
{
"X-Men Days of Future Past - 1080p.mkv",
"X-Men Days of Future Past-trailer.mp4",
"X-Men Days of Future Past-trailer2.mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestDifferentNames()
{
var files = new[]
{
"Looper (2012)-trailer.mkv",
"Looper.2012.bluray.720p.x264.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestSeparateFiles()
{
// These should be considered separate, unrelated videos
var files = new[]
{
"My video 1.mkv",
"My video 2.mkv",
"My video 3.mkv",
"My video 4.mkv",
"My video 5.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(5, result.Count);
}
[Fact]
public void TestMultiDisc()
{
var files = new[]
{
@"M:/Movies (DVD)/Movies (Musical)/Sound of Music (1965)/Sound of Music Disc 1",
@"M:/Movies (DVD)/Movies (Musical)/Sound of Music (1965)/Sound of Music Disc 2"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = true,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestPoundSign()
{
// These should be considered separate, unrelated videos
var files = new[]
{
@"My movie #1.mp4",
@"My movie #2.mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = true,
FullName = i
}).ToList()).ToList();
Assert.Equal(2, result.Count);
}
[Fact]
public void TestStackedWithTrailer()
{
var files = new[]
{
@"No (2012) part1.mp4",
@"No (2012) part2.mp4",
@"No (2012) part1-trailer.mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestStackedWithTrailer2()
{
var files = new[]
{
@"No (2012) part1.mp4",
@"No (2012) part2.mp4",
@"No (2012)-trailer.mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestExtrasByFolderName()
{
var files = new[]
{
@"/Movies/Top Gun (1984)/movie.mp4",
@"/Movies/Top Gun (1984)/Top Gun (1984)-trailer.mp4",
@"/Movies/Top Gun (1984)/Top Gun (1984)-trailer2.mp4",
@"trailer.mp4"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestDoubleTags()
{
var files = new[]
{
@"/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Counterfeit Racks (2011) Disc 1 cd1.avi",
@"/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Counterfeit Racks (2011) Disc 1 cd2.avi",
@"/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Disc 2 cd1.avi",
@"/MCFAMILY-PC/Private3$/Heterosexual/Breast In Class 2 Counterfeit Racks (2011)/Breast In Class 2 Disc 2 cd2.avi"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(2, result.Count);
}
[Fact]
public void TestArgumentOutOfRangeException()
{
var files = new[]
{
@"/nas-markrobbo78/Videos/INDEX HTPC/Movies/Watched/3 - ACTION/Argo (2012)/movie.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestColony()
{
var files = new[]
{
@"The Colony.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestFourSisters()
{
var files = new[]
{
@"Four Sisters and a Wedding - A.avi",
@"Four Sisters and a Wedding - B.avi"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestMovieTrailer()
{
var files = new[]
{
@"/Server/Despicable Me/Despicable Me (2010).mkv",
@"/Server/Despicable Me/movie-trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
[Fact]
public void TestTrailerFalsePositives()
{
var files = new[]
{
@"/Server/Despicable Me/Skyscraper (2018) - Big Game Spot.mkv",
@"/Server/Despicable Me/Skyscraper (2018) - Trailer.mkv",
@"/Server/Despicable Me/Baywatch (2017) - Big Game Spot.mkv",
@"/Server/Despicable Me/Baywatch (2017) - Trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Equal(4, result.Count);
}
[Fact]
public void TestSubfolders()
{
var files = new[]
{
@"/Movies/Despicable Me/Despicable Me.mkv",
@"/Movies/Despicable Me/trailers/trailer.mkv"
};
var resolver = GetResolver();
var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList()).ToList();
Assert.Single(result);
}
private VideoListResolver GetResolver()
{
var options = new NamingOptions();
return new VideoListResolver(options);
}
}
}

@ -0,0 +1,275 @@
using MediaBrowser.Model.Entities;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
{
public class VideoResolverTests : BaseVideoTest
{
// FIXME
// [Fact]
public void TestSimpleFile()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/Brave (2007)/Brave (2006).mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal("Brave", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestSimpleFile2()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/Bad Boys (1995)/Bad Boys (1995).mkv");
Assert.Equal(1995, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal("Bad Boys", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestSimpleFileWithNumericName()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/300 (2007)/300 (2006).mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal("300", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestExtra()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/Brave (2007)/Brave (2006)-trailer.mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal(ExtraType.Trailer, result.ExtraType);
Assert.Equal("Brave (2006)-trailer", result.Name);
}
// FIXME
// [Fact]
public void TestExtraWithNumericName()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/300 (2007)/300 (2006)-trailer.mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal("300 (2006)-trailer", result.Name);
Assert.Equal(ExtraType.Trailer, result.ExtraType);
}
// FIXME
// [Fact]
public void TestStubFileWithNumericName()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/300 (2007)/300 (2006).bluray.disc");
Assert.Equal(2006, result.Year);
Assert.True(result.IsStub);
Assert.Equal("bluray", result.StubType);
Assert.False(result.Is3D);
Assert.Equal("300", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestStubFile()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/Brave (2007)/Brave (2006).bluray.disc");
Assert.Equal(2006, result.Year);
Assert.True(result.IsStub);
Assert.Equal("bluray", result.StubType);
Assert.False(result.Is3D);
Assert.Equal("Brave", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestExtraStubWithNumericNameNotSupported()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/300 (2007)/300 (2006)-trailer.bluray.disc");
Assert.Equal(2006, result.Year);
Assert.True(result.IsStub);
Assert.Equal("bluray", result.StubType);
Assert.False(result.Is3D);
Assert.Equal("300", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestExtraStubNotSupported()
{
// Using a stub for an extra is currently not supported
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/brave (2007)/brave (2006)-trailer.bluray.disc");
Assert.Equal(2006, result.Year);
Assert.True(result.IsStub);
Assert.Equal("bluray", result.StubType);
Assert.False(result.Is3D);
Assert.Equal("brave", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void Test3DFileWithNumericName()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/300 (2007)/300 (2006).3d.sbs.mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.True(result.Is3D);
Assert.Equal("sbs", result.Format3D);
Assert.Equal("300", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestBad3DFileWithNumericName()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/300 (2007)/300 (2006).3d1.sbas.mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal("300", result.Name);
Assert.Null(result.ExtraType);
Assert.Null(result.Format3D);
}
// FIXME
// [Fact]
public void Test3DFile()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/brave (2007)/brave (2006).3d.sbs.mkv");
Assert.Equal(2006, result.Year);
Assert.False(result.IsStub);
Assert.True(result.Is3D);
Assert.Equal("sbs", result.Format3D);
Assert.Equal("brave", result.Name);
Assert.Null(result.ExtraType);
}
[Fact]
public void TestNameWithoutDate()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/American Psycho/American.Psycho.mkv");
Assert.Null(result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Null(result.Format3D);
Assert.Equal("American.Psycho", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestCleanDateAndStringsSequence()
{
var parser = GetParser();
// In this test case, running CleanDateTime first produces no date, so it will attempt to run CleanString first and then CleanDateTime again
var result =
parser.ResolveFile(@"/server/Movies/3.Days.to.Kill/3.Days.to.Kill.2014.720p.BluRay.x264.YIFY.mkv");
Assert.Equal(2014, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Null(result.Format3D);
Assert.Equal("3.Days.to.Kill", result.Name);
Assert.Null(result.ExtraType);
}
// FIXME
// [Fact]
public void TestCleanDateAndStringsSequence1()
{
var parser = GetParser();
// In this test case, running CleanDateTime first produces no date, so it will attempt to run CleanString first and then CleanDateTime again
var result =
parser.ResolveFile(@"/server/Movies/3 days to kill (2005)/3 days to kill (2005).mkv");
Assert.Equal(2005, result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Null(result.Format3D);
Assert.Equal("3 days to kill", result.Name);
Assert.Null(result.ExtraType);
}
[Fact]
public void TestFolderNameWithExtension()
{
var parser = GetParser();
var result =
parser.ResolveFile(@"/server/Movies/7 Psychos.mkv/7 Psychos.mkv");
Assert.Null(result.Year);
Assert.False(result.IsStub);
Assert.False(result.Is3D);
Assert.Equal("7 Psychos", result.Name);
Assert.Null(result.ExtraType);
}
}
}
Loading…
Cancel
Save