Fix file extension detection error (#453)

This commit is contained in:
Michael Bucari-Tovo 2023-01-18 15:47:05 -07:00
parent 9be0d58461
commit 13f522abb8
10 changed files with 86 additions and 74 deletions

View File

@ -203,7 +203,8 @@ That naming may not be desirable for everyone, but it's an easy change to instea
private FileStream createOutputFileStream(MultiConvertFileProperties multiConvertFileProperties) private FileStream createOutputFileStream(MultiConvertFileProperties multiConvertFileProperties)
{ {
var fileName = DownloadOptions.GetMultipartFileName(multiConvertFileProperties); var fileName = DownloadOptions.GetMultipartFileName(multiConvertFileProperties);
fileName = FileUtility.GetValidFilename(fileName, DownloadOptions.ReplacementCharacters); var extension = Path.GetExtension(fileName);
fileName = FileUtility.GetValidFilename(fileName, DownloadOptions.ReplacementCharacters, extension);
multiPartFilePaths.Add(fileName); multiPartFilePaths.Add(fileName);

View File

@ -93,7 +93,7 @@ namespace AaxDecrypter
try try
{ {
var path = Path.ChangeExtension(OutputFileName, ".cue"); var path = Path.ChangeExtension(OutputFileName, ".cue");
path = FileUtility.GetValidFilename(path, DownloadOptions.ReplacementCharacters); path = FileUtility.GetValidFilename(path, DownloadOptions.ReplacementCharacters, ".cue");
File.WriteAllText(path, Cue.CreateContents(Path.GetFileName(OutputFileName), DownloadOptions.ChapterInfo)); File.WriteAllText(path, Cue.CreateContents(Path.GetFileName(OutputFileName), DownloadOptions.ChapterInfo));
OnFileCreated(path); OnFileCreated(path);
} }

View File

@ -13,7 +13,7 @@ namespace FileManager
public FileNamingTemplate(string template) : base(template) { } public FileNamingTemplate(string template) : base(template) { }
/// <summary>Generate a valid path for this file or directory</summary> /// <summary>Generate a valid path for this file or directory</summary>
public LongPath GetFilePath(ReplacementCharacters replacements, bool returnFirstExisting = false) public LongPath GetFilePath(ReplacementCharacters replacements, string fileExtension, bool returnFirstExisting = false)
{ {
string fileName = string fileName =
Template.EndsWith(Path.DirectorySeparatorChar) || Template.EndsWith(Path.AltDirectorySeparatorChar) ? Template.EndsWith(Path.DirectorySeparatorChar) || Template.EndsWith(Path.AltDirectorySeparatorChar) ?
@ -44,7 +44,6 @@ namespace FileManager
var fileNamePart = pathParts[^1]; var fileNamePart = pathParts[^1];
pathParts.Remove(fileNamePart); pathParts.Remove(fileNamePart);
var fileExtension = Path.GetExtension(fileNamePart);
fileNamePart = fileNamePart[..^fileExtension.Length]; fileNamePart = fileNamePart[..^fileExtension.Length];
LongPath directory = Path.Join(pathParts.Select(p => replaceFileName(p, paramReplacements, LongPath.MaxFilenameLength)).ToArray()); LongPath directory = Path.Join(pathParts.Select(p => replaceFileName(p, paramReplacements, LongPath.MaxFilenameLength)).ToArray());
@ -56,6 +55,7 @@ namespace FileManager
.GetValidFilename( .GetValidFilename(
Path.Join(directory, replaceFileName(fileNamePart, paramReplacements, LongPath.MaxFilenameLength - fileExtension.Length - 5)) + fileExtension, Path.Join(directory, replaceFileName(fileNamePart, paramReplacements, LongPath.MaxFilenameLength - fileExtension.Length - 5)) + fileExtension,
replacements, replacements,
fileExtension,
returnFirstExisting returnFirstExisting
); );
} }

View File

@ -49,9 +49,11 @@ namespace FileManager
/// <br/>- ensure uniqueness /// <br/>- ensure uniqueness
/// <br/>- enforce max file length /// <br/>- enforce max file length
/// </summary> /// </summary>
public static LongPath GetValidFilename(LongPath path, ReplacementCharacters replacements, bool returnFirstExisting = false) public static LongPath GetValidFilename(LongPath path, ReplacementCharacters replacements, string fileExtension, bool returnFirstExisting = false)
{ {
ArgumentValidator.EnsureNotNull(path, nameof(path)); ArgumentValidator.EnsureNotNull(path, nameof(path));
ArgumentValidator.EnsureNotNull(fileExtension, nameof(fileExtension));
fileExtension = GetStandardizedExtension(fileExtension);
// remove invalid chars // remove invalid chars
path = GetSafePath(path, replacements); path = GetSafePath(path, replacements);
@ -60,21 +62,20 @@ namespace FileManager
var dir = Path.GetDirectoryName(path); var dir = Path.GetDirectoryName(path);
dir = dir?.TruncateFilename(LongPath.MaxDirectoryLength) ?? string.Empty; dir = dir?.TruncateFilename(LongPath.MaxDirectoryLength) ?? string.Empty;
var extension = Path.GetExtension(path); var fileName = Path.GetFileName(path);
var extIndex = fileName.LastIndexOf(fileExtension, StringComparison.OrdinalIgnoreCase);
var filenameWithoutExtension = extIndex >= 0 ? fileName.Remove(extIndex, fileExtension.Length) : fileName;
var fileStem
= Path.Combine(dir, filenameWithoutExtension.TruncateFilename(LongPath.MaxFilenameLength - fileExtension.Length))
.TruncateFilename(LongPath.MaxPathLength - fileExtension.Length);
var filename = Path.GetFileNameWithoutExtension(path).TruncateFilename(LongPath.MaxFilenameLength - extension.Length); var fullfilename = removeInvalidWhitespace(fileStem) + fileExtension;
var fileStem = Path.Combine(dir, filename);
var fullfilename = fileStem.TruncateFilename(LongPath.MaxPathLength - extension.Length) + extension;
fullfilename = removeInvalidWhitespace(fullfilename);
var i = 0; var i = 0;
while (File.Exists(fullfilename) && !returnFirstExisting) while (File.Exists(fullfilename) && !returnFirstExisting)
{ {
var increm = $" ({++i})"; var increm = $" ({++i})";
fullfilename = fileStem.TruncateFilename(LongPath.MaxPathLength - increm.Length - extension.Length) + increm + extension; fullfilename = fileStem.TruncateFilename(LongPath.MaxPathLength - increm.Length - fileExtension.Length) + increm + fileExtension;
} }
return fullfilename; return fullfilename;
@ -152,7 +153,8 @@ namespace FileManager
/// </summary> /// </summary>
public static string SaferMoveToValidPath(LongPath source, LongPath destination, ReplacementCharacters replacements) public static string SaferMoveToValidPath(LongPath source, LongPath destination, ReplacementCharacters replacements)
{ {
destination = GetValidFilename(destination, replacements); var extension = Path.GetExtension(source);
destination = GetValidFilename(destination, replacements, extension);
SaferMove(source, destination); SaferMove(source, destination);
return destination; return destination;
} }

View File

@ -162,14 +162,17 @@ namespace LibationAvalonia.Dialogs
Title = chapterName Title = chapterName
}; };
/*
* Path must be rooted for windows to allow long file paths. This is
* only necessary for folder templates because they may contain several
* subdirectories. Without rooting, we won't be allowed to create a
* relative path longer than MAX_PATH.
*/
var books = config.Books; var books = config.Books;
var folder = Templates.Folder.GetPortionFilename( var folder = Templates.Folder.GetPortionFilename(
libraryBookDto, libraryBookDto,
//Path must be rooted for windows to allow long file paths. This is Path.Combine(books, isFolder ? workingTemplateText : config.FolderTemplate), "");
//only necessary for folder templates because they may contain several
//subdirectories. Without rooting, we won't be allowed to create a
//relative path longer than MAX_PATH
Path.Combine(books, isFolder ? workingTemplateText : config.FolderTemplate));
folder = Path.GetRelativePath(books, folder); folder = Path.GetRelativePath(books, folder);
@ -182,7 +185,7 @@ namespace LibationAvalonia.Dialogs
"") "")
: Templates.File.GetPortionFilename( : Templates.File.GetPortionFilename(
libraryBookDto, libraryBookDto,
isFolder ? config.FileTemplate : workingTemplateText); isFolder ? config.FileTemplate : workingTemplateText, "");
var ext = config.DecryptToLossy ? "mp3" : "m4b"; var ext = config.DecryptToLossy ? "mp3" : "m4b";
var chapterTitle = Templates.ChapterTitle.GetPortionTitle(libraryBookDto, workingTemplateText, partFileProperties); var chapterTitle = Templates.ChapterTitle.GetPortionTitle(libraryBookDto, workingTemplateText, partFileProperties);

View File

@ -99,11 +99,11 @@ namespace LibationFileManager
/// <summary> /// <summary>
/// EditTemplateDialog: Get template generated filename for portion of path /// EditTemplateDialog: Get template generated filename for portion of path
/// </summary> /// </summary>
public string GetPortionFilename(LibraryBookDto libraryBookDto, string template) public string GetPortionFilename(LibraryBookDto libraryBookDto, string template, string fileExtension)
=> string.IsNullOrWhiteSpace(template) => string.IsNullOrWhiteSpace(template)
? "" ? ""
: getFileNamingTemplate(libraryBookDto, template, null, null) : getFileNamingTemplate(libraryBookDto, template, null, fileExtension)
.GetFilePath(Configuration.Instance.ReplacementCharacters).PathWithoutPrefix; .GetFilePath(Configuration.Instance.ReplacementCharacters, fileExtension).PathWithoutPrefix;
private static Regex ifSeriesRegex { get; } = new Regex("<if series->(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static Regex ifSeriesRegex { get; } = new Regex("<if series->(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
@ -215,7 +215,7 @@ namespace LibationFileManager
/// <summary>USES LIVE CONFIGURATION VALUES</summary> /// <summary>USES LIVE CONFIGURATION VALUES</summary>
public string GetFilename(LibraryBookDto libraryBookDto, string baseDir = null) public string GetFilename(LibraryBookDto libraryBookDto, string baseDir = null)
=> getFileNamingTemplate(libraryBookDto, Configuration.Instance.FolderTemplate, baseDir ?? AudibleFileStorage.BooksDirectory, null) => getFileNamingTemplate(libraryBookDto, Configuration.Instance.FolderTemplate, baseDir ?? AudibleFileStorage.BooksDirectory, null)
.GetFilePath(Configuration.Instance.ReplacementCharacters); .GetFilePath(Configuration.Instance.ReplacementCharacters, string.Empty);
#endregion #endregion
} }
@ -238,7 +238,7 @@ namespace LibationFileManager
/// <summary>USES LIVE CONFIGURATION VALUES</summary> /// <summary>USES LIVE CONFIGURATION VALUES</summary>
public string GetFilename(LibraryBookDto libraryBookDto, string dirFullPath, string extension, bool returnFirstExisting = false) public string GetFilename(LibraryBookDto libraryBookDto, string dirFullPath, string extension, bool returnFirstExisting = false)
=> getFileNamingTemplate(libraryBookDto, Configuration.Instance.FileTemplate, dirFullPath, extension) => getFileNamingTemplate(libraryBookDto, Configuration.Instance.FileTemplate, dirFullPath, extension)
.GetFilePath(Configuration.Instance.ReplacementCharacters, returnFirstExisting); .GetFilePath(Configuration.Instance.ReplacementCharacters, extension, returnFirstExisting);
#endregion #endregion
} }
@ -273,19 +273,20 @@ namespace LibationFileManager
public string GetFilename(LibraryBookDto libraryBookDto, AaxDecrypter.MultiConvertFileProperties props) public string GetFilename(LibraryBookDto libraryBookDto, AaxDecrypter.MultiConvertFileProperties props)
=> GetPortionFilename(libraryBookDto, Configuration.Instance.ChapterFileTemplate, props, AudibleFileStorage.DecryptInProgressDirectory); => GetPortionFilename(libraryBookDto, Configuration.Instance.ChapterFileTemplate, props, AudibleFileStorage.DecryptInProgressDirectory);
public string GetPortionFilename(LibraryBookDto libraryBookDto, string template, AaxDecrypter.MultiConvertFileProperties props, string fullDirPath, ReplacementCharacters replacements = null) public string GetPortionFilename(LibraryBookDto libraryBookDto, string template, AaxDecrypter.MultiConvertFileProperties props, string fullDirPath, ReplacementCharacters replacements = null)
{ {
if (string.IsNullOrWhiteSpace(template)) return string.Empty; if (string.IsNullOrWhiteSpace(template)) return string.Empty;
replacements ??= Configuration.Instance.ReplacementCharacters; replacements ??= Configuration.Instance.ReplacementCharacters;
var fileNamingTemplate = getFileNamingTemplate(libraryBookDto, template, fullDirPath, Path.GetExtension(props.OutputFileName)); var fileExtension = Path.GetExtension(props.OutputFileName);
var fileNamingTemplate = getFileNamingTemplate(libraryBookDto, template, fullDirPath, fileExtension);
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChCount, props.PartsTotal); fileNamingTemplate.AddParameterReplacement(TemplateTags.ChCount, props.PartsTotal);
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber, props.PartsPosition); fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber, props.PartsPosition);
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber0, FileUtility.GetSequenceFormatted(props.PartsPosition, props.PartsTotal)); fileNamingTemplate.AddParameterReplacement(TemplateTags.ChNumber0, FileUtility.GetSequenceFormatted(props.PartsPosition, props.PartsTotal));
fileNamingTemplate.AddParameterReplacement(TemplateTags.ChTitle, props.Title ?? ""); fileNamingTemplate.AddParameterReplacement(TemplateTags.ChTitle, props.Title ?? "");
return fileNamingTemplate.GetFilePath(replacements).PathWithoutPrefix; return fileNamingTemplate.GetFilePath(replacements, fileExtension).PathWithoutPrefix;
} }
#endregion #endregion
} }

View File

@ -98,15 +98,16 @@ namespace LibationWinForms.Dialogs
}; };
/*
* Path must be rooted for windows to allow long file paths. This is
* only necessary for folder templates because they may contain several
* subdirectories. Without rooting, we won't be allowed to create a
* relative path longer than MAX_PATH.
*/
var books = config.Books; var books = config.Books;
var folder = Templates.Folder.GetPortionFilename( var folder = Templates.Folder.GetPortionFilename(
libraryBookDto, libraryBookDto,
//Path must be rooted for windows to allow long file paths. This is Path.Combine(books, isFolder ? workingTemplateText : config.FolderTemplate), "");
//only necessary for folder templates because they may contain several
//subdirectories. Without rooting, we won't be allowed to create a
//relative path longer than MAX_PATH
Path.Combine(books, isFolder ? workingTemplateText : config.FolderTemplate));
folder = Path.GetRelativePath(books, folder); folder = Path.GetRelativePath(books, folder);
@ -119,7 +120,7 @@ namespace LibationWinForms.Dialogs
"") "")
: Templates.File.GetPortionFilename( : Templates.File.GetPortionFilename(
libraryBookDto, libraryBookDto,
isFolder ? config.FileTemplate : workingTemplateText); isFolder ? config.FileTemplate : workingTemplateText, "");
var ext = config.DecryptToLossy ? "mp3" : "m4b"; var ext = config.DecryptToLossy ? "mp3" : "m4b";
var chapterTitle = Templates.ChapterTitle.GetPortionTitle(libraryBookDto, workingTemplateText, partFileProperties); var chapterTitle = Templates.ChapterTitle.GetPortionTitle(libraryBookDto, workingTemplateText, partFileProperties);

View File

@ -33,12 +33,13 @@ namespace FileNamingTemplateTests
{ {
var template = $"<title> [<id>]"; var template = $"<title> [<id>]";
var fullfilename = Path.Combine(dirFullPath, template + FileUtility.GetStandardizedExtension(extension)); extension = FileUtility.GetStandardizedExtension(extension);
var fullfilename = Path.Combine(dirFullPath, template + extension);
var fileNamingTemplate = new FileNamingTemplate(fullfilename); var fileNamingTemplate = new FileNamingTemplate(fullfilename);
fileNamingTemplate.AddParameterReplacement("title", filename); fileNamingTemplate.AddParameterReplacement("title", filename);
fileNamingTemplate.AddParameterReplacement("id", metadataSuffix); fileNamingTemplate.AddParameterReplacement("id", metadataSuffix);
return fileNamingTemplate.GetFilePath(Replacements).PathWithoutPrefix; return fileNamingTemplate.GetFilePath(Replacements, extension).PathWithoutPrefix;
} }
[TestMethod] [TestMethod]
@ -57,12 +58,13 @@ namespace FileNamingTemplateTests
// 100-999 => 001-999 // 100-999 => 001-999
var chapterCountLeadingZeros = partsPosition.ToString().PadLeft(partsTotal.ToString().Length, '0'); var chapterCountLeadingZeros = partsPosition.ToString().PadLeft(partsTotal.ToString().Length, '0');
var t = Path.ChangeExtension(originalPath, null) + " - <chapter> - <title>" + Path.GetExtension(originalPath); var estension = Path.GetExtension(originalPath);
var t = Path.ChangeExtension(originalPath, null) + " - <chapter> - <title>" + estension;
var fileNamingTemplate = new FileNamingTemplate(t); var fileNamingTemplate = new FileNamingTemplate(t);
fileNamingTemplate.AddParameterReplacement("chapter", chapterCountLeadingZeros); fileNamingTemplate.AddParameterReplacement("chapter", chapterCountLeadingZeros);
fileNamingTemplate.AddParameterReplacement("title", suffix); fileNamingTemplate.AddParameterReplacement("title", suffix);
return fileNamingTemplate.GetFilePath(Replacements).PathWithoutPrefix; return fileNamingTemplate.GetFilePath(Replacements, estension).PathWithoutPrefix;
} }
[TestMethod] [TestMethod]
@ -74,7 +76,7 @@ namespace FileNamingTemplateTests
{ {
var fileNamingTemplate = new FileNamingTemplate(inStr); var fileNamingTemplate = new FileNamingTemplate(inStr);
fileNamingTemplate.AddParameterReplacement("title", @"s\l/a\s/h\e/s"); fileNamingTemplate.AddParameterReplacement("title", @"s\l/a\s/h\e/s");
fileNamingTemplate.GetFilePath(Replacements).PathWithoutPrefix.Should().Be(outStr); fileNamingTemplate.GetFilePath(Replacements, "txt").PathWithoutPrefix.Should().Be(outStr);
} }
} }
} }

View File

@ -197,30 +197,30 @@ namespace FileUtilityTests
[TestMethod] [TestMethod]
// dot-files // dot-files
[DataRow(@"C:\a bc\x y z\.f i l e.txt", PlatformID.Win32NT)] [DataRow(@"C:\a bc\x y z\.f i l e.txt", "txt", PlatformID.Win32NT)]
[DataRow(@"/a bc/x y z/.f i l e.txt", PlatformID.Unix)] [DataRow(@"/a bc/x y z/.f i l e.txt", "txt", PlatformID.Unix)]
// dot-folders // dot-folders
[DataRow(@"C:\a bc\.x y z\f i l e.txt", PlatformID.Win32NT)] [DataRow(@"C:\a bc\.x y z\f i l e.txt", "txt", PlatformID.Win32NT)]
[DataRow(@"/a bc/.x y z/f i l e.txt", PlatformID.Unix)] [DataRow(@"/a bc/.x y z/f i l e.txt", "txt", PlatformID.Unix)]
public void Valid(string input, PlatformID platformID) => Tests(input, input, platformID); public void Valid(string input, string extension, PlatformID platformID) => Tests(input, extension, input, platformID);
[TestMethod] [TestMethod]
// folder spaces // folder spaces
[DataRow(@"C:\ a bc \x y z ", @"C:\a bc\x y z", PlatformID.Win32NT)] [DataRow(@"C:\ a bc \x y z ","", @"C:\a bc\x y z", PlatformID.Win32NT)]
[DataRow(@"/ a bc /x y z ", @"/a bc/x y z", PlatformID.Unix)] [DataRow(@"/ a bc /x y z ", "", @"/a bc/x y z", PlatformID.Unix)]
// file spaces // file spaces
[DataRow(@"C:\a bc\x y z\ f i l e.txt ", @"C:\a bc\x y z\f i l e.txt", PlatformID.Win32NT)] [DataRow(@"C:\a bc\x y z\ f i l e.txt ", "txt", @"C:\a bc\x y z\f i l e.txt", PlatformID.Win32NT)]
[DataRow(@"/a bc/x y z/ f i l e.txt ", @"/a bc/x y z/f i l e.txt", PlatformID.Unix)] [DataRow(@"/a bc/x y z/ f i l e.txt ", "txt", @"/a bc/x y z/f i l e.txt", PlatformID.Unix)]
// eliminate beginning space and end dots and spaces // eliminate beginning space and end dots and spaces
[DataRow(@"C:\a bc\ . . . x y z . . . \f i l e.txt", @"C:\a bc\. . . x y z\f i l e.txt", PlatformID.Win32NT)] [DataRow(@"C:\a bc\ . . . x y z . . . \f i l e.txt", "txt", @"C:\a bc\. . . x y z\f i l e.txt", PlatformID.Win32NT)]
[DataRow(@"/a bc/ . . . x y z . . . /f i l e.txt", @"/a bc/. . . x y z/f i l e.txt", PlatformID.Unix)] [DataRow(@"/a bc/ . . . x y z . . . /f i l e.txt", "txt", @"/a bc/. . . x y z/f i l e.txt", PlatformID.Unix)]
// file end dots // file end dots
[DataRow(@"C:\a bc\x y z\f i l e.txt . . .", @"C:\a bc\x y z\f i l e.txt", PlatformID.Win32NT)] [DataRow(@"C:\a bc\x y z\f i l e.txt . . .", "txt", @"C:\a bc\x y z\f i l e.txt", PlatformID.Win32NT)]
[DataRow(@"/a bc/x y z/f i l e.txt . . .", @"/a bc/x y z/f i l e.txt", PlatformID.Unix)] [DataRow(@"/a bc/x y z/f i l e.txt . . .", "txt", @"/a bc/x y z/f i l e.txt", PlatformID.Unix)]
public void Tests(string input, string expected, PlatformID platformID) public void Tests(string input, string extension, string expected, PlatformID platformID)
{ {
if (Environment.OSVersion.Platform == platformID) if (Environment.OSVersion.Platform == platformID)
FileUtility.GetValidFilename(input, Replacements).PathWithoutPrefix.Should().Be(expected); FileUtility.GetValidFilename(input, Replacements, extension).PathWithoutPrefix.Should().Be(expected);
} }
} }

View File

@ -81,23 +81,25 @@ namespace TemplatesTests
=> Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension); => Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension);
[TestMethod] [TestMethod]
[DataRow("f.txt", @"C:\foo\bar", null, @"C:\foo\bar\f.txt", PlatformID.Win32NT)] [DataRow("f.txt", @"C:\foo\bar", "", @"C:\foo\bar\f.txt", PlatformID.Win32NT)]
[DataRow("f.txt", @"/foo/bar", null, @"/foo/bar/f.txt", PlatformID.Unix)] [DataRow("f.txt", @"/foo/bar", "", @"/foo/bar/f.txt", PlatformID.Unix)]
[DataRow("f.txt", @"C:\foo\bar", "ext", @"C:\foo\bar\f.txt.ext", PlatformID.Win32NT)] [DataRow("f.txt", @"C:\foo\bar", ".ext", @"C:\foo\bar\f.txt.ext", PlatformID.Win32NT)]
[DataRow("f.txt", @"/foo/bar", "ext", @"/foo/bar/f.txt.ext", PlatformID.Unix)] [DataRow("f.txt", @"/foo/bar", ".ext", @"/foo/bar/f.txt.ext", PlatformID.Unix)]
[DataRow("f", @"C:\foo\bar", "ext", @"C:\foo\bar\f.ext", PlatformID.Win32NT)] [DataRow("f", @"C:\foo\bar", ".ext", @"C:\foo\bar\f.ext", PlatformID.Win32NT)]
[DataRow("f", @"/foo/bar", "ext", @"/foo/bar/f.ext", PlatformID.Unix)] [DataRow("f", @"/foo/bar", ".ext", @"/foo/bar/f.ext", PlatformID.Unix)]
[DataRow("<id>", @"C:\foo\bar", "ext", @"C:\foo\bar\asin.ext", PlatformID.Win32NT)] [DataRow("<id>", @"C:\foo\bar", ".ext", @"C:\foo\bar\asin.ext", PlatformID.Win32NT)]
[DataRow("<id>", @"/foo/bar", "ext", @"/foo/bar/asin.ext", PlatformID.Unix)] [DataRow("<id>", @"/foo/bar", ".ext", @"/foo/bar/asin.ext", PlatformID.Unix)]
[DataRow("<bitrate> - <samplerate> - <channels>", @"C:\foo\bar", "ext", @"C:\foo\bar\128 - 44100 - 2.ext", PlatformID.Win32NT)] [DataRow("<bitrate> - <samplerate> - <channels>", @"C:\foo\bar", ".ext", @"C:\foo\bar\128 - 44100 - 2.ext", PlatformID.Win32NT)]
[DataRow("<bitrate> - <samplerate> - <channels>", @"/foo/bar", "ext", @"/foo/bar/128 - 44100 - 2.ext", PlatformID.Unix)] [DataRow("<bitrate> - <samplerate> - <channels>", @"/foo/bar", ".ext", @"/foo/bar/128 - 44100 - 2.ext", PlatformID.Unix)]
[DataRow("<year> - <channels>", @"C:\foo\bar", "ext", @"C:\foo\bar\2017 - 2.ext", PlatformID.Win32NT)] [DataRow("<year> - <channels>", @"C:\foo\bar", ".ext", @"C:\foo\bar\2017 - 2.ext", PlatformID.Win32NT)]
[DataRow("<year> - <channels>", @"/foo/bar", "ext", @"/foo/bar/2017 - 2.ext", PlatformID.Unix)] [DataRow("<year> - <channels>", @"/foo/bar", ".ext", @"/foo/bar/2017 - 2.ext", PlatformID.Unix)]
public void Tests(string template, string dirFullPath, string extension, string expected, PlatformID platformID) [DataRow("(000.0) <year> - <channels>", @"C:\foo\bar", "ext", @"C:\foo\bar\(000.0) 2017 - 2.ext", PlatformID.Win32NT)]
[DataRow("(000.0) <year> - <channels>", @"/foo/bar", ".ext", @"/foo/bar/(000.0) 2017 - 2.ext", PlatformID.Unix)]
public void Tests(string template, string dirFullPath, string extension, string expected, PlatformID platformID)
{ {
if (Environment.OSVersion.Platform == platformID) if (Environment.OSVersion.Platform == platformID)
Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension) Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension)
.GetFilePath(Replacements) .GetFilePath(Replacements, extension)
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(expected); .Should().Be(expected);
} }
@ -109,7 +111,7 @@ namespace TemplatesTests
{ {
if (Environment.OSVersion.Platform == platformID) if (Environment.OSVersion.Platform == platformID)
Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series-><-if series>bar", directory, "ext") Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series-><-if series>bar", directory, "ext")
.GetFilePath(Replacements) .GetFilePath(Replacements, ".ext")
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(expected); .Should().Be(expected);
} }
@ -121,7 +123,7 @@ namespace TemplatesTests
{ {
if (Environment.OSVersion.Platform == platformID) if (Environment.OSVersion.Platform == platformID)
Templates.getFileNamingTemplate(GetLibraryBook(null), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext") Templates.getFileNamingTemplate(GetLibraryBook(null), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext")
.GetFilePath(Replacements) .GetFilePath(Replacements, ".ext")
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(expected); .Should().Be(expected);
} }
@ -133,7 +135,7 @@ namespace TemplatesTests
{ {
if (Environment.OSVersion.Platform == platformID) if (Environment.OSVersion.Platform == platformID)
Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext") Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series->-<series>-<id>-<-if series>bar", directory, "ext")
.GetFilePath(Replacements) .GetFilePath(Replacements, ".ext")
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(expected); .Should().Be(expected);
} }