unit tests

This commit is contained in:
John Andrews
2024-08-22 17:09:36 +12:00
parent b1d24ec69c
commit f239934937
13 changed files with 370 additions and 351 deletions
+1
View File
@@ -24,6 +24,7 @@ This plugin is required for FileFlows to work.</Description>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.4.3" />
<PackageReference Include="MSTest.TestFramework" Version="3.4.3" />
<PackageReference Include="Moq" Version="4.20.70" />
</ItemGroup>
<ItemGroup>
<Reference Include="Plugin">
+1 -1
View File
@@ -27,7 +27,7 @@ public class FileSizeCompare : Node
if (result.IsFailed)
{
// try get from variables
if (args.Variables.ContainsKey("file.Orig.Size") && args.Variables["file.Orig.Size"] is long tSize && tSize > 0)
if (args.Variables.TryGetValue("file.Orig.Size", out object? value) && value is long tSize && tSize > 0)
{
origSize = tSize;
}
+28 -26
View File
@@ -134,22 +134,22 @@ public class HasHardLinks: Node
if(string.IsNullOrWhiteSpace(error) == false)
args.Logger?.ILog("Error Output: " + error);
if (int.TryParse(output.Trim(), out var linkCount))
if (int.TryParse(output.Trim(), out var linkCount) == false)
{
if (linkCount > 0)
{
args.Logger?.ILog($"The file has {linkCount} hard links.");
if (linkCount >= count)
return true;
}
args.Logger?.ILog("The file does not have the required number of hard links.");
args.Logger?.ILog("Failed to retrieve link count.");
return false;
}
--linkCount;
if(string.IsNullOrWhiteSpace(error))
args.Logger?.ELog(error);
args.Logger?.ILog("Failed to retrieve link count.");
if (linkCount > 0)
{
args.Logger?.ILog($"The file has {linkCount} hard links.");
if (linkCount >= count)
return true;
}
args.Logger?.ILog("The file does not have the required number of hard links.");
return false;
}
catch (Exception ex)
@@ -184,26 +184,28 @@ public class HasHardLinks: Node
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if(string.IsNullOrWhiteSpace(output) == false)
if (string.IsNullOrWhiteSpace(output) == false)
args.Logger?.ILog("Standard Output: " + output);
if(string.IsNullOrWhiteSpace(error) == false)
if (string.IsNullOrWhiteSpace(error) == false)
args.Logger?.ILog("Error Output: " + error);
if (int.TryParse(output.Trim(), out var linkCount))
if (int.TryParse(output.Trim(), out var linkCount) == false)
{
if (linkCount > 0)
{
args.Logger?.ILog($"The file has {linkCount} hard links.");
if (linkCount >= count)
return true;
}
args.Logger?.ILog("The file does not have hard links.");
return false;
args.Logger?.ILog("The file does not have the required number of hard links.");
return false;
}
linkCount -= 1; // every file has at least one hard link we want the additional hard links
args.Logger?.ILog("The file does not have the required number of hard links.");
return false;
if (linkCount > 0)
{
args.Logger?.ILog($"The file has {linkCount} hard links.");
if (linkCount >= count)
return true;
}
args.Logger?.ILog("The file does not have hard links.");
return false;
}
catch (Exception ex)
{
-78
View File
@@ -1,78 +0,0 @@
using FileFlows.Plugin;
#if(DEBUG)
namespace BasicNodes.Tests;
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
[TestClass]
public class CopyTests
{
List<KeyValuePair<string, string>> Mappings = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("/usr/local/bin/ffmpeg", @"C:\Users\username\AppData\Roaming\FileFlows\Tools\ffmpeg.exe"),
new KeyValuePair<string, string>("/mnt/tempNAS/media/dvd/sorted", @"\\192.168.1.22\Media\dvd\sorted"),
new KeyValuePair<string, string>("/mnt/tempNAS/media/dvd/output", @"\\192.168.1.22\Media\dvd\output"),
};
char DirectorySeperatorChar = System.IO.Path.DirectorySeparatorChar;
[TestMethod]
public void CopyTests_Dir_Mapping()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv", logger, false, string.Empty, null);
args.PathMapper = s => Map(s);
CopyFile node = new ();
node.CopyFolder = true;
node.DestinationPath = "/mnt/tempNAS/media/dvd/output";
node.DestinationFile = "{file.Orig.FileName}p.DVD.x264.slow.CRF16{ext}";
var result = node.Execute(args);
Assert.AreEqual(2, result);
}
[TestMethod]
public void CopyTests_Dir_DateReplacements()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"D:\videos\testfiles\bigbuckbunny_480p_30s.mp4", logger, false, string.Empty, null);
args.PathMapper = s => Map(s);
CopyFile node = new();
node.CopyFolder = true;
node.DestinationPath = @"D:\videos\converted";
node.DestinationFile = "{file.Orig.FileName}-{file.Create.Month:00}-{file.Create.Year}{ext!}";
var result = node.Execute(args);
Assert.AreEqual(1, result);
}
string Map(string path)
{
if (string.IsNullOrEmpty(path))
return string.Empty;
if (Mappings != null && Mappings.Count > 0)
{
// convert all \ to / for now
path = path.Replace("\\", "/");
foreach (var mapping in Mappings)
{
if (string.IsNullOrEmpty(mapping.Value) || string.IsNullOrEmpty(mapping.Key))
continue;
string pattern = Regex.Escape(mapping.Key.Replace("\\", "/"));
string replacement = mapping.Value.Replace("\\", "/");
path = Regex.Replace(path, "^" + pattern, replacement, RegexOptions.IgnoreCase);
}
// now convert / to path charcter
if (DirectorySeperatorChar != '/')
path = path.Replace('/', DirectorySeperatorChar);
if (path.StartsWith("//")) // special case for SMB paths
path = path.Replace('/', '\\');
}
return path;
}
}
#endif
+35 -25
View File
@@ -1,35 +1,45 @@
#if(DEBUG)
namespace BasicNodes.Tests
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
using FileFlows.Plugin;
using Moq;
namespace BasicNodes.Tests;
[TestClass]
public class ExecutorTests : TestBase
{
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
private Mock<IProcessHelper> mockProcessHelper = new();
[TestClass]
public class ExecutorTests
protected override void TestStarting()
{
[TestMethod]
public void Executor_OutputVariable()
mockProcessHelper.Setup(x => x.ExecuteShellCommand(It.IsAny<ExecuteArgs>())).Returns(Task.FromResult(new ProcessResult()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv", logger, false, string.Empty, null);
ExitCode = 0,
Completed = true,
Output = "this is the output",
StandardOutput = "this is the standard output",
StandardError = "this is the standard error"
}));
}
Executor node = new Executor();
string file = @"D:\Videos\dummy.mkv";
node.FileName = @"C:\utils\ffmpeg\ffmpeg.exe";
node.Arguments = "-i \"" + file + "\"";
node.OutputVariable = "ExecOutput";
var result = node.Execute(args);
Assert.IsTrue(args.Variables.ContainsKey("ExecOutput"));
string output = args.Variables["ExecOutput"] as string;
Assert.IsNotNull(output);
}
[TestMethod]
public void Executor_VariablePattern_Tests()
{
Assert.IsFalse(Regex.IsMatch(string.Empty, Executor.VariablePattern));
}
[TestMethod]
public void Executor_OutputVariable()
{
var args = new NodeParameters(@"c:\test\testfile.mkv", Logger, false, string.Empty, MockFileService.Object);
args.Process = mockProcessHelper.Object;
Executor node = new Executor();
string file = @"D:\Videos\dummy.mkv";
node.FileName = @"C:\utils\ffmpeg\ffmpeg.exe";
node.Arguments = "-i \"" + file + "\"";
node.OutputVariable = "ExecOutput";
var result = node.Execute(args);
Assert.IsTrue(args.Variables.ContainsKey("ExecOutput"));
string output = args.Variables["ExecOutput"] as string;
Assert.IsNotNull(output);
}
}
+87 -89
View File
@@ -1,116 +1,114 @@
#if(DEBUG)
using System.IO;
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BasicNodes.Tests
namespace BasicNodes.Tests;
[TestClass]
public class FileSizeCompareTests : TestBase
{
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class FileSizeCompareTests
private string CreateFile(int size)
{
private string CreateFile(int size)
{
string tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
System.IO.File.WriteAllText(tempFile, new string('a', size));
return tempFile;
string tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".tmp");
System.IO.File.WriteAllText(tempFile, new string('a', size * 1000));
return tempFile;
}
[TestMethod]
public void FileSize_Shrunk()
{
string tempFile = CreateFile(2);
var args = new FileFlows.Plugin.NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
}
[TestMethod]
public void FileSize_Shrunk()
{
string tempFile = CreateFile(2);
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(tempFile, logger, false, string.Empty, null);
string wfFile = CreateFile(1);
args.SetWorkingFile(wfFile);
string wfFile = CreateFile(1);
args.SetWorkingFile(wfFile);
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(1, result);
}
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(1, result);
}
[TestMethod]
public void FileSize_Grew()
{
string tempFile = CreateFile(2);
var args = new FileFlows.Plugin.NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
[TestMethod]
public void FileSize_Grew()
{
string tempFile = CreateFile(2);
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(tempFile, logger, false, string.Empty, null);
string wfFile = CreateFile(20);
args.SetWorkingFile(wfFile);
string wfFile = CreateFile(20);
args.SetWorkingFile(wfFile);
FileSizeCompare node = new ();
int result = node.Execute(args);
Assert.AreEqual(3, result);
}
FileSizeCompare node = new ();
int result = node.Execute(args);
Assert.AreEqual(3, result);
}
[TestMethod]
public void FileSize_SameSize()
{
string tempFile = CreateFile(2);
var args = new FileFlows.Plugin.NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
[TestMethod]
public void FileSize_SameSize()
{
string tempFile = CreateFile(2);
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(tempFile, logger, false, string.Empty, null);
string wfFile = CreateFile(2);
args.SetWorkingFile(wfFile);
string wfFile = CreateFile(2);
args.SetWorkingFile(wfFile);
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(2, result);
}
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(2, result);
}
[TestMethod]
public void FileSize_Shrunk_OriginalDeleted()
{
string tempFile = CreateFile(2);
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(tempFile, logger, false, string.Empty, null);
Assert.IsTrue(args.WorkingFileSize > 0);
System.IO.File.Delete(tempFile);
[TestMethod]
public void FileSize_Shrunk_OriginalDeleted()
{
string tempFile = CreateFile(2);
var args = new FileFlows.Plugin.NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
Assert.IsTrue(args.WorkingFileSize > 0);
System.IO.File.Delete(tempFile);
string wfFile = CreateFile(1);
args.SetWorkingFile(wfFile);
string wfFile = CreateFile(1);
args.SetWorkingFile(wfFile);
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(1, result);
}
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(1, result);
}
[TestMethod]
public void FileSize_Grew_OriginalDeleted()
{
string tempFile = CreateFile(2);
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(tempFile, logger, false, string.Empty, null);
System.IO.File.Delete(tempFile);
[TestMethod]
public void FileSize_Grew_OriginalDeleted()
{
string tempFile = CreateFile(2);
var args = new FileFlows.Plugin.NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
System.IO.File.Delete(tempFile);
string wfFile = CreateFile(20);
args.SetWorkingFile(wfFile);
string wfFile = CreateFile(20);
args.SetWorkingFile(wfFile);
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(3, result);
}
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(3, result);
}
[TestMethod]
public void FileSize_SameSize_OriginalDeleted()
{
string tempFile = CreateFile(2);
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(tempFile, logger, false, string.Empty, null);
System.IO.File.Delete(tempFile);
[TestMethod]
public void FileSize_SameSize_OriginalDeleted()
{
string tempFile = CreateFile(2);
var args = new FileFlows.Plugin.NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
System.IO.File.Delete(tempFile);
string wfFile = CreateFile(2);
args.SetWorkingFile(wfFile);
string wfFile = CreateFile(2);
args.SetWorkingFile(wfFile);
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(2, result);
}
FileSizeCompare node = new();
int result = node.Execute(args);
Assert.AreEqual(2, result);
}
}
+75 -6
View File
@@ -1,18 +1,87 @@
#if(DEBUG)
namespace BasicNodes.Tests;
using System.Diagnostics;
using System.IO;
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BasicNodes.Tests;
[TestClass]
public class HasHardLinksTest
public class HasHardLinksTest : TestBase
{
private string? testFile;
protected override void TestCleanUp()
{
// Clean up the original file and any hard links created
if (string.IsNullOrEmpty(testFile) == false && System.IO.File.Exists(testFile))
{
try
{
// Delete the original file
System.IO.File.Delete(testFile);
// Delete the hard links
for (int i = 1; ; i++)
{
var linkName = $"{testFile}_link{i}";
if (System.IO.File.Exists(linkName))
System.IO.File.Delete(linkName);
else
break; // Stop if the link doesn't exist
}
}
catch (Exception ex)
{
// Log or handle the cleanup exception if necessary
Logger.ILog($"Failed to clean up files: {ex.Message}");
}
}
}
public static void CreateHardLinkFile(string filename, int hardlinks = 1)
{
// Ensure the file exists
System.IO.File.WriteAllText(filename, "Test content");
// Create the specified number of hard links
for (int i = 1; i <= hardlinks; i++)
{
string linkName = $"{filename}_link{i}";
// Use the `ln` command to create a hard link
Process process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "ln",
Arguments = $"{filename} {linkName}",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
process.WaitForExit();
if (process.ExitCode != 0)
{
string error = process.StandardError.ReadToEnd();
throw new InvalidOperationException($"Failed to create hard link: {error}");
}
}
}
[TestMethod]
public void HasHardLink()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/john/temp/test.file", logger, false, string.Empty, new LocalFileService());;
testFile = Path.GetTempFileName();
CreateHardLinkFile(testFile, 2);
var args = new FileFlows.Plugin.NodeParameters(testFile, Logger, false, string.Empty, MockFileService.Object);
HasHardLinks element = new ();
@@ -23,8 +92,8 @@ public class HasHardLinksTest
[TestMethod]
public void NoHardLinks()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/john/temp/other.test", logger, false, string.Empty, new LocalFileService());;
testFile = Path.GetTempFileName();
var args = new FileFlows.Plugin.NodeParameters(testFile, Logger, false, string.Empty, MockFileService.Object);
HasHardLinks element = new ();
+22 -25
View File
@@ -1,33 +1,31 @@
#if(DEBUG)
namespace BasicNodes.Tests;
using System.IO;
using FileFlows.Plugin;
using FileFlows.BasicNodes.File;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
namespace BasicNodes.Tests;
[TestClass]
public class MoveTests
public class MoveTests : TestBase
{
[TestMethod]
public void MoveTests_Variable_Filename()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", Logger, false, string.Empty, new LocalFileService());
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.Name}");
Assert.AreEqual(@"D:/test/tv4a-starwarsrebels.s01e15-1080p.mkv", dest);
}
[TestMethod]
public void MoveTests_Variable_FilenameExt()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", Logger, false, string.Empty, new LocalFileService());
// ensure we dont double up the extension after FF-154
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.Name}{file.Extension}");
@@ -38,20 +36,22 @@ public class MoveTests
[TestMethod]
public void MoveTests_Variable_FilenameNoExtension()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var tempFileNoExtension = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
var tempFile = tempFileNoExtension + ".tmp";
System.IO.File.WriteAllText(tempFile, "this is a temp file");
var args = new NodeParameters(tempFile, Logger, false, string.Empty, new LocalFileService());
args.InitFile(tempFile);
// ensure we dont double up the extension after FF-154
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.NameNoExtension}");
string dest = MoveFile.GetDestinationPath(args, Path.GetTempPath(), "{file.NameNoExtension}");
Assert.AreEqual(@"D:/test/tv4a-starwarsrebels.mkv", dest);
Assert.AreEqual(tempFileNoExtension, dest);
}
[TestMethod]
public void MoveTests_Variable_Ext()
{
var logger = new TestLogger();
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", Logger, false, string.Empty, new LocalFileService());
// ensure we dont double up the extension after FF-154
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.Name}{ext}");
@@ -62,18 +62,17 @@ public class MoveTests
[TestMethod]
public void MoveTests_Variable_Original_Filename()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", Logger, false, string.Empty, new LocalFileService());
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.Orig.FileName}");
Assert.AreEqual(@"D:/test/tv4a-starwarsrebels.s01e15-1080p.mkv", dest);
}
[TestMethod]
public void MoveTests_Variable_Original_FilenameExt()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", Logger, false, string.Empty, new LocalFileService());
// ensure we dont double up the extension after FF-154
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.Orig.FileName}{file.Orig.Extension}");
@@ -83,8 +82,8 @@ public class MoveTests
[TestMethod]
public void MoveTests_Variable_Original_NoExtension()
{
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/user/test/tv4a-starwarsrebels.s01e15-1080p.mkv", Logger, false, string.Empty, new LocalFileService());
// ensure we dont double up the extension after FF-154
string dest = MoveFile.GetDestinationPath(args, @"D:\test", "{file.Orig.FileNameNoExtension}");
@@ -95,8 +94,8 @@ public class MoveTests
[TestMethod]
public void MoveTests_MoveFolder()
{
var logger = new TestLogger();
var args = new NodeParameters(@"\\tower\downloads\downloaded\tv\The.Walking.Dead.Dead.City.S01E04\some-file.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"\\tower\downloads\downloaded\tv\The.Walking.Dead.Dead.City.S01E04\some-file.mkv", Logger, false, string.Empty, new LocalFileService());
args.RelativeFile = @"The.Walking.Dead.Dead.City.S01E04\some-file.mkv";
string dest = MoveFile.GetDestinationPath(args, @"\\tower\downloads\converted\tv", null, moveFolder:true);
@@ -111,14 +110,12 @@ public class MoveTests
[TestMethod]
public void MoveTests_AdditionalFiles()
{
var logger = new TestLogger();
var args = new NodeParameters(@"/home/john/Videos/move-me/dir/basic.mkv", logger, false, string.Empty, null);
var args = new NodeParameters(@"/home/john/Videos/move-me/dir/basic.mkv", Logger, false, string.Empty, new LocalFileService());
var ele = new MoveFile();
ele.AdditionalFiles = new[] { "*.srt" };
ele.DestinationPath = "/home/john/Videos/converted";
var result = ele.Execute(args);
var log = logger.ToString();
Assert.AreEqual(1, result);
}
}
+4 -4
View File
@@ -12,7 +12,7 @@ public class WriteTextTests : TestBase
[TestMethod]
public void WorkingFile_Csv()
{
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService());
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, MockFileService.Object);
var output = WriteText.GetText(args, "", "file.csv");
Assert.AreEqual("\"/test/file.mkv\"", output);
@@ -21,7 +21,7 @@ public class WriteTextTests : TestBase
[TestMethod]
public void WorkingFile_Text()
{
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService());
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, MockFileService.Object);
var output = WriteText.GetText(args, "", "file.txt");
Assert.AreEqual("/test/file.mkv", output);
@@ -30,7 +30,7 @@ public class WriteTextTests : TestBase
[TestMethod]
public void CsvArgs()
{
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService());
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, MockFileService.Object);
args.Variables["file.Name"] = "file.mkv";
args.Variables["ext"] = "mkv";
@@ -41,7 +41,7 @@ public class WriteTextTests : TestBase
[TestMethod]
public void CsvArg()
{
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService());
var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, MockFileService.Object);
args.Variables["file.Name"] = "file.mkv";
var output = WriteText.GetText(args, "{file.Name}", "file.csv");
+14
View File
@@ -4,6 +4,9 @@ using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using FileFlows.BasicNodes;
using FileFlows.Plugin.Helpers;
using FileFlows.Plugin.Services;
using Moq;
namespace BasicNodes.Tests;
@@ -20,6 +23,8 @@ public abstract class TestBase
internal TestLogger Logger = new();
protected Mock<IFileService> MockFileService = new();
/// <summary>
/// Gets or sets the test context
/// </summary>
@@ -38,6 +43,8 @@ public abstract class TestBase
[TestInitialize]
public void TestInitialize()
{
FileHelper.DontChangeOwner = true;
FileHelper.DontSetPermissions = true;
Logger.Writer = (msg) => TestContext.WriteLine(msg);
this.TestPath = this.TestPath?.EmptyAsNull() ?? (IsLinux ? "~/src/ff-files/test-files/videos" : @"d:\videos\testfiles");
@@ -48,11 +55,14 @@ public abstract class TestBase
if (Directory.Exists(this.TempPath) == false)
Directory.CreateDirectory(this.TempPath);
TestStarting();
}
[TestCleanup]
public void CleanUp()
{
TestCleanUp();
TestContext.WriteLine(Logger.ToString());
}
@@ -60,6 +70,10 @@ public abstract class TestBase
{
}
protected virtual void TestCleanUp()
{
}
}
+103 -97
View File
@@ -1,102 +1,108 @@
namespace FileFlows.BasicNodes.File
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
namespace FileFlows.BasicNodes.File;
/// <summary>
/// Executes a command
/// </summary>
public class Executor : Node
{
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
/// <inheritdoc />
public override int Inputs => 1;
/// <inheritdoc />
public override int Outputs => 2;
/// <inheritdoc />
public override FlowElementType Type => FlowElementType.Process;
/// <inheritdoc />
public override string Icon => "fas fa-terminal";
/// <inheritdoc />
public override string HelpUrl => "https://fileflows.com/docs/plugins/basic-nodes/executor";
public class Executor : Node
internal const string VariablePattern = @"(^[\s]*$)|(^([a-zA-Z_]+)[a-zA-Z_0-9]*$)";
[Required]
[File(1)]
public string FileName { get; set; }
[Required]
[TextVariable(2)]
public string Arguments { get; set; }
[Folder(3)]
public string WorkingDirectory { get; set; }
[Required]
[NumberInt(4)]
public int SuccessCode { get; set; }
[NumberInt(5)]
public int Timeout { get; set; }
[Text(6)]
[System.ComponentModel.DataAnnotations.RegularExpression(VariablePattern)]
public string OutputVariable { get; set; }
[Text(7)]
[System.ComponentModel.DataAnnotations.RegularExpression(VariablePattern)]
public string OutputErrorVariable { get; set; }
private NodeParameters args;
/// <inheritdoc />
public override Task Cancel()
{
public override int Inputs => 1;
public override int Outputs => 2;
public override FlowElementType Type => FlowElementType.Process;
public override string Icon => "fas fa-terminal";
public override string HelpUrl => "https://fileflows.com/docs/plugins/basic-nodes/executor";
internal const string VariablePattern = @"(^[\s]*$)|(^([a-zA-Z_]+)[a-zA-Z_0-9]*$)";
[Required]
[File(1)]
public string FileName { get; set; }
[Required]
[TextVariable(2)]
public string Arguments { get; set; }
[Folder(3)]
public string WorkingDirectory { get; set; }
[Required]
[NumberInt(4)]
public int SuccessCode { get; set; }
[NumberInt(5)]
public int Timeout { get; set; }
[Text(6)]
[System.ComponentModel.DataAnnotations.RegularExpression(VariablePattern)]
public string OutputVariable { get; set; }
[Text(7)]
[System.ComponentModel.DataAnnotations.RegularExpression(VariablePattern)]
public string OutputErrorVariable { get; set; }
private NodeParameters args;
public override Task Cancel()
{
args?.Process?.Cancel();
return Task.CompletedTask;
}
public override int Execute(NodeParameters args)
{
this.args = args;
string pArgs = args.ReplaceVariables(Arguments ?? string.Empty);
string filename = args.ReplaceVariables(FileName ?? string.Empty, stripMissing: true);
string workingDirectory = args.ReplaceVariables(WorkingDirectory ?? string.Empty, stripMissing: true);
var task = args.Process.ExecuteShellCommand(new ExecuteArgs
{
Command = filename,
Arguments = pArgs,
Timeout = Timeout,
WorkingDirectory = workingDirectory
});
task.Wait();
if(task.Result.Completed == false)
{
args.Logger?.ELog("Process failed to complete");
return -1;
}
bool success = task.Result.ExitCode == this.SuccessCode;
if(string.IsNullOrWhiteSpace(OutputVariable) == false && Regex.IsMatch(OutputVariable, VariablePattern))
{
args.UpdateVariables(new Dictionary<string, object>
{
{ OutputVariable, task.Result.StandardOutput }
});
}
if (string.IsNullOrWhiteSpace(OutputErrorVariable) == false && Regex.IsMatch(OutputErrorVariable ?? string.Empty, VariablePattern))
{
args.UpdateVariables(new Dictionary<string, object>
{
{ OutputErrorVariable, task.Result.StandardError }
});
}
if (success)
return 1;
else
{
args.Logger?.ILog("Unsuccesful exit code returned: " + task.Result.ExitCode);
return 2;
}
}
args?.Process?.Cancel();
return Task.CompletedTask;
}
/// <inheritdoc />
public override int Execute(NodeParameters args)
{
this.args = args;
string pArgs = args.ReplaceVariables(Arguments ?? string.Empty);
string filename = args.ReplaceVariables(FileName ?? string.Empty, stripMissing: true);
string workingDirectory = args.ReplaceVariables(WorkingDirectory ?? string.Empty, stripMissing: true);
var task = args.Process.ExecuteShellCommand(new ExecuteArgs
{
Command = filename,
Arguments = pArgs,
Timeout = Timeout,
WorkingDirectory = workingDirectory
});
task.Wait();
if(task.Result.Completed == false)
{
args.Logger?.ELog("Process failed to complete");
return -1;
}
bool success = task.Result.ExitCode == this.SuccessCode;
if(string.IsNullOrWhiteSpace(OutputVariable) == false && Regex.IsMatch(OutputVariable, VariablePattern))
{
args.UpdateVariables(new Dictionary<string, object>
{
{ OutputVariable, task.Result.StandardOutput }
});
}
if (string.IsNullOrWhiteSpace(OutputErrorVariable) == false && Regex.IsMatch(OutputErrorVariable ?? string.Empty, VariablePattern))
{
args.UpdateVariables(new Dictionary<string, object>
{
{ OutputErrorVariable, task.Result.StandardError }
});
}
if (success)
return 1;
else
{
args.Logger?.ILog("Unsuccesful exit code returned: " + task.Result.ExitCode);
return 2;
}
}
}
Binary file not shown.
Binary file not shown.