Explorar el Código

Merge pull request #2257 from Bond-009/cleantests

Fix a couple of tests
dkanada hace 5 años
padre
commit
c618f3f8eb

+ 3 - 4
Emby.Naming/Common/NamingOptions.cs

@@ -177,13 +177,12 @@ namespace Emby.Naming.Common
 
             CleanDateTimes = new[]
             {
-                @"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](\d{4})([ _\,\.\(\)\[\]\-][^\d]|).*(\d{4})*"
+                @"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19\d{2}|20\d{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19\d{2}|20\d{2})*"
             };
 
             CleanStrings = new[]
             {
-                @"[ _\,\.\(\)\[\]\-](ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
-                @"[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
+                @"[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|HDR|HDC|UHD|UltraHD|4k|ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
                 @"(\[.*\])"
             };
 
@@ -340,7 +339,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

+ 15 - 56
Emby.Naming/Video/CleanDateTimeParser.cs

@@ -1,89 +1,48 @@
 #pragma warning disable CS1591
 #pragma warning disable SA1600
+#nullable enable
 
-using System;
+using System.Collections.Generic;
 using System.Globalization;
-using System.IO;
-using System.Linq;
 using System.Text.RegularExpressions;
-using Emby.Naming.Common;
 
 namespace Emby.Naming.Video
 {
     /// <summary>
     /// <see href="http://kodi.wiki/view/Advancedsettings.xml#video" />.
     /// </summary>
-    public class CleanDateTimeParser
+    public static class CleanDateTimeParser
     {
-        private readonly NamingOptions _options;
-
-        public CleanDateTimeParser(NamingOptions options)
+        public static CleanDateTimeResult Clean(string name, IReadOnlyList<Regex> cleanDateTimeRegexes)
         {
-            _options = options;
-        }
-
-        public CleanDateTimeResult Clean(string name)
-        {
-            var originalName = name;
-
-            try
+            CleanDateTimeResult result = new CleanDateTimeResult(name);
+            var len = cleanDateTimeRegexes.Count;
+            for (int i = 0; i < len; i++)
             {
-                var extension = Path.GetExtension(name) ?? string.Empty;
-                // Check supported extensions
-                if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)
-                    && !_options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
+                if (TryClean(name, cleanDateTimeRegexes[i], ref result))
                 {
-                    // Dummy up a file extension because the expressions will fail without one
-                    // This is tricky because we can't just check Path.GetExtension for empty
-                    // If the input is "St. Vincent (2014)", it will produce ". Vincent (2014)" as the extension
-                    name += ".mkv";
+                    return result;
                 }
             }
-            catch (ArgumentException)
-            {
-            }
-
-            var result = _options.CleanDateTimeRegexes.Select(i => Clean(name, i))
-                .FirstOrDefault(i => i.HasChanged) ??
-                new CleanDateTimeResult { Name = originalName };
-
-            if (result.HasChanged)
-            {
-                return result;
-            }
-
-            // Make a second pass, running clean string first
-            var cleanStringResult = new CleanStringParser().Clean(name, _options.CleanStringRegexes);
 
-            if (!cleanStringResult.HasChanged)
-            {
-                return result;
-            }
-
-            return _options.CleanDateTimeRegexes.Select(i => Clean(cleanStringResult.Name, i))
-                .FirstOrDefault(i => i.HasChanged) ??
-                result;
+            return result;
         }
 
-        private static CleanDateTimeResult Clean(string name, Regex expression)
+        private static bool TryClean(string name, Regex expression, ref CleanDateTimeResult result)
         {
-            var result = new CleanDateTimeResult();
-
             var match = expression.Match(name);
 
             if (match.Success
-                && match.Groups.Count == 4
+                && match.Groups.Count == 5
                 && match.Groups[1].Success
                 && match.Groups[2].Success
                 && int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
             {
-                name = match.Groups[1].Value;
-                result.Year = year;
-                result.HasChanged = true;
+                result = new CleanDateTimeResult(match.Groups[1].Value.TrimEnd(), year);
+                return true;
             }
 
-            result.Name = name;
-            return result;
+            return false;
         }
     }
 }

+ 18 - 11
Emby.Naming/Video/CleanDateTimeResult.cs

@@ -1,26 +1,33 @@
 #pragma warning disable CS1591
 #pragma warning disable SA1600
+#nullable enable
 
 namespace Emby.Naming.Video
 {
-    public class CleanDateTimeResult
+    public readonly struct CleanDateTimeResult
     {
+        public CleanDateTimeResult(string name, int? year)
+        {
+            Name = name;
+            Year = year;
+        }
+
+        public CleanDateTimeResult(string name)
+        {
+            Name = name;
+            Year = null;
+        }
+
         /// <summary>
-        /// Gets or sets the name.
+        /// Gets the name.
         /// </summary>
         /// <value>The name.</value>
-        public string Name { get; set; }
+        public string Name { get; }
 
         /// <summary>
-        /// Gets or sets the year.
+        /// Gets the year.
         /// </summary>
         /// <value>The year.</value>
-        public int? Year { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance has changed.
-        /// </summary>
-        /// <value><c>true</c> if this instance has changed; otherwise, <c>false</c>.</value>
-        public bool HasChanged { get; set; }
+        public int? Year { get; }
     }
 }

+ 17 - 24
Emby.Naming/Video/CleanStringParser.cs

@@ -1,6 +1,8 @@
 #pragma warning disable CS1591
 #pragma warning disable SA1600
+#nullable enable
 
+using System;
 using System.Collections.Generic;
 using System.Text.RegularExpressions;
 
@@ -9,44 +11,35 @@ namespace Emby.Naming.Video
     /// <summary>
     /// <see href="http://kodi.wiki/view/Advancedsettings.xml#video" />.
     /// </summary>
-    public class CleanStringParser
+    public static class CleanStringParser
     {
-        public CleanStringResult Clean(string name, IEnumerable<Regex> expressions)
+        public static bool TryClean(string name, IReadOnlyList<Regex> expressions, out ReadOnlySpan<char> newName)
         {
-            var hasChanged = false;
-
-            foreach (var exp in expressions)
+            var len = expressions.Count;
+            for (int i = 0; i < len; i++)
             {
-                var result = Clean(name, exp);
-
-                if (!string.IsNullOrEmpty(result.Name))
+                if (TryClean(name, expressions[i], out newName))
                 {
-                    name = result.Name;
-                    hasChanged = hasChanged || result.HasChanged;
+                    return true;
                 }
             }
 
-            return new CleanStringResult
-            {
-                Name = name,
-                HasChanged = hasChanged
-            };
+            newName = ReadOnlySpan<char>.Empty;
+            return false;
         }
 
-        private static CleanStringResult Clean(string name, Regex expression)
+        private static bool TryClean(string name, Regex expression, out ReadOnlySpan<char> newName)
         {
-            var result = new CleanStringResult();
-
             var match = expression.Match(name);
-
-            if (match.Success)
+            int index = match.Index;
+            if (match.Success && index != 0)
             {
-                result.HasChanged = true;
-                name = name.Substring(0, match.Index);
+                newName = name.AsSpan().Slice(0, match.Index);
+                return true;
             }
 
-            result.Name = name;
-            return result;
+            newName = string.Empty;
+            return false;
         }
     }
 }

+ 0 - 20
Emby.Naming/Video/CleanStringResult.cs

@@ -1,20 +0,0 @@
-#pragma warning disable CS1591
-#pragma warning disable SA1600
-
-namespace Emby.Naming.Video
-{
-    public class CleanStringResult
-    {
-        /// <summary>
-        /// Gets or sets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance has changed.
-        /// </summary>
-        /// <value><c>true</c> if this instance has changed; otherwise, <c>false</c>.</value>
-        public bool HasChanged { get; set; }
-    }
-}

+ 6 - 5
Emby.Naming/Video/VideoResolver.cs

@@ -94,9 +94,10 @@ namespace Emby.Naming.Video
             {
                 var cleanDateTimeResult = CleanDateTime(name);
 
-                if (extraResult.ExtraType == null)
+                if (extraResult.ExtraType == null
+                    && TryCleanString(cleanDateTimeResult.Name, out ReadOnlySpan<char> newName))
                 {
-                    name = CleanString(cleanDateTimeResult.Name).Name;
+                    name = newName.ToString();
                 }
 
                 year = cleanDateTimeResult.Year;
@@ -130,14 +131,14 @@ namespace Emby.Naming.Video
             return _options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
         }
 
-        public CleanStringResult CleanString(string name)
+        public bool TryCleanString(string name, out ReadOnlySpan<char> newName)
         {
-            return new CleanStringParser().Clean(name, _options.CleanStringRegexes);
+            return CleanStringParser.TryClean(name, _options.CleanStringRegexes, out newName);
         }
 
         public CleanDateTimeResult CleanDateTime(string name)
         {
-            return new CleanDateTimeParser(_options).Clean(name);
+            return CleanDateTimeParser.Clean(name, _options.CleanDateTimeRegexes);
         }
     }
 }

+ 6 - 15
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -36,7 +36,6 @@ using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Library;
 using MediaBrowser.Model.Net;
@@ -54,6 +53,9 @@ namespace Emby.Server.Implementations.Library
     /// </summary>
     public class LibraryManager : ILibraryManager
     {
+        private NamingOptions _namingOptions;
+        private string[] _videoFileExtensions;
+
         /// <summary>
         /// Gets or sets the postscan tasks.
         /// </summary>
@@ -2508,21 +2510,11 @@ namespace Emby.Server.Implementations.Library
         }
 
         public NamingOptions GetNamingOptions()
-        {
-            return GetNamingOptionsInternal();
-        }
-
-        private NamingOptions _namingOptions;
-        private string[] _videoFileExtensions;
-
-        private NamingOptions GetNamingOptionsInternal()
         {
             if (_namingOptions == null)
             {
-                var options = new NamingOptions();
-
-                _namingOptions = options;
-                _videoFileExtensions = _namingOptions.VideoFileExtensions.ToArray();
+                _namingOptions = new NamingOptions();
+                _videoFileExtensions = _namingOptions.VideoFileExtensions;
             }
 
             return _namingOptions;
@@ -2533,11 +2525,10 @@ namespace Emby.Server.Implementations.Library
             var resolver = new VideoResolver(GetNamingOptions());
 
             var result = resolver.CleanDateTime(name);
-            var cleanName = resolver.CleanString(result.Name);
 
             return new ItemLookupInfo
             {
-                Name = cleanName.Name,
+                Name = resolver.TryCleanString(result.Name, out var newName) ? newName.ToString() : result.Name,
                 Year = result.Year
             };
         }

+ 3 - 5
tests/Jellyfin.Naming.Tests/Video/BaseVideoTest.cs

@@ -5,11 +5,9 @@ namespace Jellyfin.Naming.Tests.Video
 {
     public abstract class BaseVideoTest
     {
-        protected VideoResolver GetParser()
-        {
-            var options = new NamingOptions();
+        private readonly NamingOptions _namingOptions = new NamingOptions();
 
-            return new VideoResolver(options);
-        }
+        protected VideoResolver GetParser()
+            => new VideoResolver(_namingOptions);
     }
 }

+ 44 - 128
tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs

@@ -1,143 +1,59 @@
 using System.IO;
+using Emby.Naming.Common;
+using Emby.Naming.Video;
 using Xunit;
 
 namespace Jellyfin.Naming.Tests.Video
 {
-    public class CleanDateTimeTests : BaseVideoTest
+    public sealed class CleanDateTimeTests
     {
-        // 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)
+        private readonly NamingOptions _namingOptions = new NamingOptions();
+
+        [Theory]
+        [InlineData(@"The Wolf of Wall Street (2013).mkv", "The Wolf of Wall Street", 2013)]
+        [InlineData(@"The Wolf of Wall Street 2 (2013).mkv", "The Wolf of Wall Street 2", 2013)]
+        [InlineData(@"The Wolf of Wall Street - 2 (2013).mkv", "The Wolf of Wall Street - 2", 2013)]
+        [InlineData(@"The Wolf of Wall Street 2001 (2013).mkv", "The Wolf of Wall Street 2001", 2013)]
+        [InlineData(@"300 (2006).mkv", "300", 2006)]
+        [InlineData(@"d:/movies/300 (2006).mkv", "300", 2006)]
+        [InlineData(@"300 2 (2006).mkv", "300 2", 2006)]
+        [InlineData(@"300 - 2 (2006).mkv", "300 - 2", 2006)]
+        [InlineData(@"300 2001 (2006).mkv", "300 2001", 2006)]
+        [InlineData(@"curse.of.chucky.2013.stv.unrated.multi.1080p.bluray.x264-rough", "curse.of.chucky", 2013)]
+        [InlineData(@"curse.of.chucky.2013.stv.unrated.multi.2160p.bluray.x264-rough", "curse.of.chucky", 2013)]
+        [InlineData(@"/server/Movies/300 (2007)/300 (2006).bluray.disc", "300", 2006)]
+        [InlineData(@"Arrival.2016.2160p.Blu-Ray.HEVC.mkv", "Arrival", 2016)]
+        [InlineData(@"The Wolf of Wall Street (2013)", "The Wolf of Wall Street", 2013)]
+        [InlineData(@"The Wolf of Wall Street 2 (2013)", "The Wolf of Wall Street 2", 2013)]
+        [InlineData(@"The Wolf of Wall Street - 2 (2013)", "The Wolf of Wall Street - 2", 2013)]
+        [InlineData(@"The Wolf of Wall Street 2001 (2013)", "The Wolf of Wall Street 2001", 2013)]
+        [InlineData(@"300 (2006)", "300", 2006)]
+        [InlineData(@"d:/movies/300 (2006)", "300", 2006)]
+        [InlineData(@"300 2 (2006)", "300 2", 2006)]
+        [InlineData(@"300 - 2 (2006)", "300 - 2", 2006)]
+        [InlineData(@"300 2001 (2006)", "300 2001", 2006)]
+        [InlineData(@"/server/Movies/300 (2007)/300 (2006)", "300", 2006)]
+        [InlineData(@"/server/Movies/300 (2007)/300 (2006).mkv", "300", 2006)]
+        [InlineData(@"American.Psycho.mkv", "American.Psycho.mkv", null)]
+        [InlineData(@"American Psycho.mkv", "American Psycho.mkv", null)]
+        [InlineData(@"[rec].mkv", "[rec].mkv", null)]
+        [InlineData(@"St. Vincent (2014)", "St. Vincent", 2014)]
+        [InlineData("Super movie(2009).mp4", "Super movie", 2009)]
+        // FIXME: [InlineData("Drug War 2013.mp4", "Drug War", 2013)]
+        [InlineData("My Movie (1997) - GreatestReleaseGroup 2019.mp4", "My Movie", 1997)]
+        // FIXME: [InlineData("First Man 2018 1080p.mkv", "First Man", 2018)]
+        [InlineData("First Man (2018) 1080p.mkv", "First Man", 2018)]
+        // FIXME: [InlineData("Maximum Ride - 2016 - WEBDL-1080p - x264 AC3.mkv", "Maximum Ride", 2016)]
+        // FIXME: [InlineData("Robin Hood [Multi-Subs] [2018].mkv", "Robin Hood", 2018)]
+        [InlineData(@"3.Days.to.Kill.2014.720p.BluRay.x264.YIFY.mkv", "3.Days.to.Kill", 2014)] // In this test case, running CleanDateTime first produces no date, so it will attempt to run CleanString first and then CleanDateTime again
+        public void CleanDateTimeTest(string input, string expectedName, int? expectedYear)
         {
             input = Path.GetFileName(input);
 
-            var result = GetParser().CleanDateTime(input);
+            var result = new VideoResolver(_namingOptions).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);
-        }
     }
 }

+ 36 - 124
tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs

@@ -1,133 +1,45 @@
 using System;
-using System.Globalization;
+using Emby.Naming.Common;
+using Emby.Naming.Video;
 using Xunit;
 
 namespace Jellyfin.Naming.Tests.Video
 {
-    public class CleanStringTests : BaseVideoTest
+    public sealed class CleanStringTests
     {
-        // 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);
+        private readonly NamingOptions _namingOptions = new NamingOptions();
+
+        [Theory]
+        [InlineData("Super movie 480p.mp4", "Super movie")]
+        [InlineData("Super movie 480p 2001.mp4", "Super movie")]
+        [InlineData("Super movie [480p].mp4", "Super movie")]
+        [InlineData("480 Super movie [tmdbid=12345].mp4", "480 Super movie")]
+        [InlineData("Super movie(2009).mp4", "Super movie(2009).mp4")]
+        [InlineData("Run lola run (lola rennt) (2009).mp4", "Run lola run (lola rennt) (2009).mp4")]
+        [InlineData(@"American.Psycho.mkv", "American.Psycho.mkv")]
+        [InlineData(@"American Psycho.mkv", "American Psycho.mkv")]
+        [InlineData(@"[rec].mkv", "[rec].mkv")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.4k.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.UltraHD.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.UHD.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.HDR.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.HDC.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon-HDC.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.BDrip.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.BDrip-HDC.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        [InlineData("Crouching.Tiger.Hidden.Dragon.4K.UltraHD.HDR.BDrip-HDC.mkv", "Crouching.Tiger.Hidden.Dragon")]
+        // FIXME: [InlineData("After The Sunset - [0004].mkv", "After The Sunset")]
+        public void CleanStringTest(string input, string expectedName)
+        {
+            if (new VideoResolver(_namingOptions).TryCleanString(input, out ReadOnlySpan<char> newName))
+            {
+                // TODO: compare spans when XUnit supports it
+                Assert.Equal(expectedName, newName.ToString());
+            }
+            else
+            {
+                Assert.Equal(expectedName, input);
+            }
         }
     }
 }

+ 0 - 1
tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs

@@ -62,7 +62,6 @@ namespace Jellyfin.Naming.Tests.Video
         [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",

+ 0 - 26
tests/Jellyfin.Naming.Tests/Video/StackTests.cs

@@ -382,32 +382,6 @@ namespace Jellyfin.Naming.Tests.Video
             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()
         {