using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Moq; using RobotNet10.ScriptEngine; using RobotNet10.ScriptEngine.HubContexts; using RobotNet10.ScriptEngine.Models; using RobotNet10.ScriptEngine.Shared; using RobotNet10.ScriptEngine.Test.Helpers; using RobotNet10.Shared; namespace RobotNet10.ScriptEngine.Test; [TestFixture] public class TaskManagerTests { private TaskManager _taskManager = null!; private VariableManager _variableManager = null!; private Mock _mockResource = null!; [SetUp] public void SetUp() { _variableManager = new VariableManager(); _mockResource = TestHelpers.CreateMockScriptResource(); var mockLogger = TestHelpers.CreateMockLogger(); var mockScopeFactory = Mock.Of(); var mockConsoleHubContext = TestHelpers.CreateMockConsoleHubContext(); var configuration = TestHelpers.CreateMockConfiguration(); _taskManager = new TaskManager( _variableManager, _mockResource.Object, mockLogger.Object, mockScopeFactory, mockConsoleHubContext.Object, configuration); } [TearDown] public void TearDown() { _taskManager?.Dispose(); } [Test] public void Load_WithValidTasks_ShouldLoadSuccessfully() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner), new ScriptTaskModel("Task2", 2000, true, "code", runner) }; // Act var result = _taskManager.Load(taskModels); // Assert Assert.That(result.IsSuccess, Is.True); Assert.That(_taskManager.Tasks.Count, Is.EqualTo(2)); Assert.That(_taskManager.Tasks.ContainsKey("Task1"), Is.True); Assert.That(_taskManager.Tasks.ContainsKey("Task2"), Is.True); } [Test] public void Load_WithNullTasks_ShouldThrowArgumentNullException() { // Act & Assert Assert.Throws(() => _taskManager.Load(null!)); } [Test] public void Start_ShouldTransitionToRunning() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner) }; _taskManager.Load(taskModels); // Act var result = _taskManager.Start(); // Assert Assert.That(result.IsSuccess, Is.True); Thread.Sleep(500); Assert.That(_taskManager.State, Is.EqualTo(TaskManagerState.Running)); } [Test] public void Stop_ShouldTransitionToIdle() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner) }; _taskManager.Load(taskModels); _taskManager.Start(); Thread.Sleep(500); // Act var result = _taskManager.Stop(); // Assert Assert.That(result.IsSuccess, Is.True); Thread.Sleep(2000); Assert.That(_taskManager.State, Is.EqualTo(TaskManagerState.Idle)); } [Test] public void EnableTask_WithExistingTask_ShouldSucceed() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner) }; _taskManager.Load(taskModels); _taskManager.Start(); // Act var result = _taskManager.EnableTask("Task1"); // Assert Assert.That(result.IsSuccess, Is.True); } [Test] public void DisableTask_WithExistingTask_ShouldSucceed() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner) }; _taskManager.Load(taskModels); _taskManager.Start(); _taskManager.EnableTask("Task1"); // Act var result = _taskManager.DisableTask("Task1"); // Assert Assert.That(result.IsSuccess, Is.True); } [Test] public void GetScriptTasks_ShouldReturnAllTasks() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner), new ScriptTaskModel("Task2", 2000, false, "code", runner) }; _taskManager.Load(taskModels); // Act var result = _taskManager.GetScriptTasks(); // Assert Assert.That(result.Length, Is.EqualTo(2)); Assert.That(result.Any(t => t.Name == "Task1"), Is.True); Assert.That(result.Any(t => t.Name == "Task2"), Is.True); } [Test] public void Reset_ShouldClearAllTasks() { // Arrange var script = CSharpScript.Create( "await Task.Delay(10);", Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default, typeof(ScriptGlobals)); var runner = script.CreateDelegate(); var taskModels = new[] { new ScriptTaskModel("Task1", 1000, false, "code", runner) }; _taskManager.Load(taskModels); Assert.That(_taskManager.Tasks.Count, Is.EqualTo(1)); // Act var result = _taskManager.Reset(); // Assert Assert.That(result.IsSuccess, Is.True); Assert.That(_taskManager.Tasks.Count, Is.EqualTo(0)); } }