Initial commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using RobotNet10.Script;
|
||||
using RobotNet10.ScriptEngine.HubContexts;
|
||||
using RobotNet10.ScriptEngine.Models;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEngine.Test.Helpers;
|
||||
|
||||
public static class TestHelpers
|
||||
{
|
||||
public static Mock<IScriptEngineResource> CreateMockScriptResource()
|
||||
{
|
||||
var mock = new Mock<IScriptEngineResource>();
|
||||
mock.Setup(x => x.GetTaskGlobals()).Returns(new Dictionary<string, object?>());
|
||||
mock.Setup(x => x.GetMissionGlobals(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).Returns(new Dictionary<string, object?>());
|
||||
mock.Setup(x => x.AppGlobalType).Returns(typeof(object));
|
||||
mock.Setup(x => x.UsingNamespaces).Returns(System.Collections.Immutable.ImmutableArray<string>.Empty);
|
||||
mock.Setup(x => x.Modules).Returns(System.Collections.Immutable.ImmutableArray<string>.Empty);
|
||||
return mock;
|
||||
}
|
||||
|
||||
public static Mock<ILogger<ScriptEngineGlobals>> CreateMockLogger()
|
||||
{
|
||||
return new Mock<ILogger<ScriptEngineGlobals>>();
|
||||
}
|
||||
|
||||
public static Mock<IServiceScopeFactory> CreateMockScopeFactory(IServiceProvider serviceProvider)
|
||||
{
|
||||
var mockScope = new Mock<IServiceScope>();
|
||||
mockScope.Setup(x => x.ServiceProvider).Returns(serviceProvider);
|
||||
|
||||
var mockScopeFactory = new Mock<IServiceScopeFactory>();
|
||||
mockScopeFactory.Setup(x => x.CreateScope()).Returns(mockScope.Object);
|
||||
|
||||
return mockScopeFactory;
|
||||
}
|
||||
|
||||
public static Mock<ConsoleHubContext> CreateMockConsoleHubContext()
|
||||
{
|
||||
return new Mock<ConsoleHubContext>(Mock.Of<Microsoft.AspNetCore.SignalR.IHubContext<RobotNet10.ScriptEngine.Hubs.ConsoleHub>>());
|
||||
}
|
||||
|
||||
public static IConfiguration CreateMockConfiguration()
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>())
|
||||
.Build();
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public static Mock<Microsoft.AspNetCore.SignalR.IHubContext<RobotNet10.ScriptEngine.Hubs.ScriptManagerHub>> CreateMockHubContext()
|
||||
{
|
||||
return new Mock<Microsoft.AspNetCore.SignalR.IHubContext<RobotNet10.ScriptEngine.Hubs.ScriptManagerHub>>();
|
||||
}
|
||||
|
||||
public static Mock<RobotNet10.Script.ILogger> CreateMockScriptLogger()
|
||||
{
|
||||
return new Mock<RobotNet10.Script.ILogger>();
|
||||
}
|
||||
|
||||
public static ScriptGlobals CreateTestScriptGlobals(RobotNet10.Script.ILogger logger, IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
var scriptEngineGlobals = new ScriptEngineGlobals(logger, scopeFactory);
|
||||
var robotNetDict = new Dictionary<string, object?>
|
||||
{
|
||||
["get_Logger"] = new Func<RobotNet10.Script.ILogger>(() => logger)
|
||||
};
|
||||
var appApisDict = new Dictionary<string, object?>();
|
||||
var globalVariablesDict = new Dictionary<string, object?>();
|
||||
var missionParametersDict = new Dictionary<string, object?>();
|
||||
|
||||
return new ScriptGlobals(robotNetDict, appApisDict, globalVariablesDict, missionParametersDict);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using RobotNet10.Script;
|
||||
using RobotNet10.ScriptEngine;
|
||||
using RobotNet10.ScriptEngine.Data;
|
||||
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 MissionManagerTests
|
||||
{
|
||||
private MissionManager _missionManager = null!;
|
||||
private VariableManager _variableManager = null!;
|
||||
private Mock<IScriptEngineResource> _mockResource = null!;
|
||||
private Mock<IServiceScopeFactory> _mockScopeFactory = null!;
|
||||
private IServiceProvider _serviceProvider = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_variableManager = new VariableManager();
|
||||
_mockResource = TestHelpers.CreateMockScriptResource();
|
||||
var mockLogger = TestHelpers.CreateMockLogger();
|
||||
var mockConsoleHubContext = TestHelpers.CreateMockConsoleHubContext();
|
||||
var configuration = TestHelpers.CreateMockConfiguration();
|
||||
|
||||
// Setup service provider with DbContext
|
||||
var services = new ServiceCollection();
|
||||
services.AddDbContext<ScriptEngineDbContext>(options =>
|
||||
options.UseInMemoryDatabase($"TestDb_{Guid.NewGuid()}"));
|
||||
_serviceProvider = services.BuildServiceProvider();
|
||||
_mockScopeFactory = TestHelpers.CreateMockScopeFactory(_serviceProvider);
|
||||
|
||||
_missionManager = new MissionManager(
|
||||
_mockScopeFactory.Object,
|
||||
_variableManager,
|
||||
_mockResource.Object,
|
||||
mockLogger.Object,
|
||||
mockConsoleHubContext.Object,
|
||||
configuration);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_missionManager?.Dispose();
|
||||
(_serviceProvider as IDisposable)?.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Load_WithValidMissions_ShouldLoadSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create<IAsyncEnumerable<MissionStatus>>(
|
||||
"yield return new MissionStatus(100, \"Success\");",
|
||||
Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
|
||||
var missionModels = new[]
|
||||
{
|
||||
new ScriptMissionModel("Mission1", new List<ScriptMissionParameterModel>(), "code", 100, false, false, runner),
|
||||
new ScriptMissionModel("Mission2", new List<ScriptMissionParameterModel>(), "code", 200, false, false, runner)
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _missionManager.Load(missionModels);
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Assert.That(_missionManager.MissionModels.Count, Is.EqualTo(2));
|
||||
Assert.That(_missionManager.MissionModels.ContainsKey("Mission1"), Is.True);
|
||||
Assert.That(_missionManager.MissionModels.ContainsKey("Mission2"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Load_WithNullMissions_ShouldThrowArgumentNullException()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentNullException>(() => _missionManager.Load(null!));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateMission_WithValidMission_ShouldReturnMissionId()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create<IAsyncEnumerable<MissionStatus>>(
|
||||
"yield return new MissionStatus(100, \"Success\");",
|
||||
Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
var missionModels = new[]
|
||||
{
|
||||
new ScriptMissionModel("Mission1", new List<ScriptMissionParameterModel>(), "code", 100, false, false, runner)
|
||||
};
|
||||
_missionManager.Load(missionModels);
|
||||
_missionManager.Start();
|
||||
|
||||
// Act
|
||||
var result = _missionManager.CreateMission("Mission1", new Dictionary<string, object?>());
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Assert.That(result.Data, Is.Not.EqualTo(Guid.Empty));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateMission_WithNonExistentMission_ShouldFail()
|
||||
{
|
||||
// Arrange
|
||||
_missionManager.Start();
|
||||
|
||||
// Act
|
||||
var result = _missionManager.CreateMission("NonExistent", new Dictionary<string, object?>());
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetScriptMissions_ShouldReturnAllMissionModels()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create<IAsyncEnumerable<MissionStatus>>(
|
||||
"yield return new MissionStatus(100, \"Success\");",
|
||||
Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
var missionModels = new[]
|
||||
{
|
||||
new ScriptMissionModel("Mission1", new List<ScriptMissionParameterModel>(), "code", 100, false, false, runner),
|
||||
new ScriptMissionModel("Mission2", new List<ScriptMissionParameterModel>(), "code", 200, false, false, runner)
|
||||
};
|
||||
_missionManager.Load(missionModels);
|
||||
|
||||
// Act
|
||||
var result = _missionManager.GetScriptMissions();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.Length, Is.EqualTo(2));
|
||||
Assert.That(result.Any(m => m.Name == "Mission1"), Is.True);
|
||||
Assert.That(result.Any(m => m.Name == "Mission2"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Reset_ShouldClearAllMissions()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create<IAsyncEnumerable<MissionStatus>>(
|
||||
"yield return new MissionStatus(100, \"Success\");",
|
||||
Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
var missionModels = new[]
|
||||
{
|
||||
new ScriptMissionModel("Mission1", new List<ScriptMissionParameterModel>(), "code", 100, false, false, runner)
|
||||
};
|
||||
_missionManager.Load(missionModels);
|
||||
Assert.That(_missionManager.MissionModels.Count, Is.EqualTo(1));
|
||||
|
||||
// Act
|
||||
var result = _missionManager.Reset();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Assert.That(_missionManager.MissionModels.Count, Is.EqualTo(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="8.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="NUnit" Version="4.5.0" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.11.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Commons\RobotNet10.ScriptEngine\RobotNet10.ScriptEngine.csproj" />
|
||||
<ProjectReference Include="..\..\Commons\RobotNet10.Script\RobotNet10.Script.csproj" />
|
||||
<ProjectReference Include="..\..\Shared\RobotNet10.ScriptEngine.Shared\RobotNet10.ScriptEngine.Shared.csproj" />
|
||||
<ProjectReference Include="..\..\Shared\RobotNet10.Shared\RobotNet10.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="NUnit.Framework" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,175 @@
|
||||
using Moq;
|
||||
using RobotNet10.ScriptEngine.Helpers;
|
||||
using RobotNet10.ScriptEngine.Models;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
using RobotNet10.ScriptEngine.Test.Helpers;
|
||||
|
||||
namespace RobotNet10.ScriptEngine.Test;
|
||||
|
||||
[TestFixture]
|
||||
public class ScriptBuilderTests
|
||||
{
|
||||
private ScriptBuilder _scriptBuilder = null!;
|
||||
private Mock<IScriptEngineResource> _mockResource = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_mockResource = TestHelpers.CreateMockScriptResource();
|
||||
_scriptBuilder = new ScriptBuilder(_mockResource.Object, "dlls");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithValidScript_ShouldExtractVariables()
|
||||
{
|
||||
// Arrange
|
||||
var script = @"
|
||||
using RobotNet10.Script;
|
||||
|
||||
public class DummyClass
|
||||
{
|
||||
[Variable]
|
||||
public int TestInt = 42;
|
||||
|
||||
[Variable]
|
||||
public string TestString = ""Hello"";
|
||||
}
|
||||
";
|
||||
|
||||
// Act
|
||||
_scriptBuilder.Build(script, out var variables, out var tasks, out var missions);
|
||||
|
||||
// Assert
|
||||
Assert.That(variables, Is.Not.Null);
|
||||
Assert.That(variables.Count(), Is.EqualTo(2));
|
||||
Assert.That(variables.Any(v => v.Name == "TestInt"), Is.True);
|
||||
Assert.That(variables.Any(v => v.Name == "TestString"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithValidScript_ShouldExtractTasks()
|
||||
{
|
||||
// Arrange
|
||||
var script = @"
|
||||
using RobotNet10.Script;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class DummyClass
|
||||
{
|
||||
[Task(1000, true)]
|
||||
public async Task TestTask()
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
// Act
|
||||
_scriptBuilder.Build(script, out var variables, out var tasks, out var missions);
|
||||
|
||||
// Assert
|
||||
Assert.That(tasks, Is.Not.Null);
|
||||
Assert.That(tasks.Count(), Is.EqualTo(1));
|
||||
Assert.That(tasks.First().Name, Is.EqualTo("TestTask"));
|
||||
Assert.That(tasks.First().Interval, Is.EqualTo(1000));
|
||||
Assert.That(tasks.First().AutoStart, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithValidScript_ShouldExtractMissions()
|
||||
{
|
||||
// Arrange
|
||||
var script = @"
|
||||
using RobotNet10.Script;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
public class DummyClass
|
||||
{
|
||||
[Mission]
|
||||
public async IAsyncEnumerable<MissionStatus> TestMission(CancellationToken ct)
|
||||
{
|
||||
yield return MissionStatus.Running;
|
||||
yield return MissionStatus.Success;
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
// Act
|
||||
_scriptBuilder.Build(script, out var variables, out var tasks, out var missions);
|
||||
|
||||
// Assert
|
||||
Assert.That(missions, Is.Not.Null);
|
||||
Assert.That(missions.Count(), Is.EqualTo(1));
|
||||
Assert.That(missions.First().Name, Is.EqualTo("TestMission"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithInvalidScript_ShouldThrowScriptCompilationException()
|
||||
{
|
||||
// Arrange
|
||||
var script = @"
|
||||
public class DummyClass
|
||||
{
|
||||
invalid syntax here
|
||||
}
|
||||
";
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ScriptCompilationException>(() =>
|
||||
_scriptBuilder.Build(script, out _, out _, out _));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithEmptyScript_ShouldReturnEmptyCollections()
|
||||
{
|
||||
// Arrange
|
||||
var script = @"
|
||||
public class DummyClass
|
||||
{
|
||||
}
|
||||
";
|
||||
|
||||
// Act
|
||||
_scriptBuilder.Build(script, out var variables, out var tasks, out var missions);
|
||||
|
||||
// Assert
|
||||
Assert.That(variables.Count(), Is.EqualTo(0));
|
||||
Assert.That(tasks.Count(), Is.EqualTo(0));
|
||||
Assert.That(missions.Count(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithMultipleTasks_ShouldExtractAll()
|
||||
{
|
||||
// Arrange
|
||||
var script = @"
|
||||
using RobotNet10.Script;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class DummyClass
|
||||
{
|
||||
[Task(1000, true)]
|
||||
public async Task Task1()
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
[Task(2000, false)]
|
||||
public async Task Task2()
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
// Act
|
||||
_scriptBuilder.Build(script, out var variables, out var tasks, out var missions);
|
||||
|
||||
// Assert
|
||||
Assert.That(tasks.Count(), Is.EqualTo(2));
|
||||
Assert.That(tasks.Any(t => t.Name == "Task1"), Is.True);
|
||||
Assert.That(tasks.Any(t => t.Name == "Task2"), Is.True);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using RobotNet10.Script;
|
||||
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 ScriptEngineGlobalsTests
|
||||
{
|
||||
private Mock<ILogger> _mockLogger = null!;
|
||||
private Mock<IServiceScopeFactory> _mockScopeFactory = null!;
|
||||
private Mock<IServiceProvider> _mockServiceProvider = null!;
|
||||
private Mock<IServiceScope> _mockScope = null!;
|
||||
private ScriptEngineGlobals _scriptEngineGlobals = null!;
|
||||
private VariableManager _variableManager = null!;
|
||||
private TaskManager _taskManager = null!;
|
||||
private MissionManager _missionManager = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_mockLogger = TestHelpers.CreateMockScriptLogger();
|
||||
_mockServiceProvider = new Mock<IServiceProvider>();
|
||||
_mockScope = new Mock<IServiceScope>();
|
||||
_mockScope.Setup(x => x.ServiceProvider).Returns(_mockServiceProvider.Object);
|
||||
_mockScopeFactory = new Mock<IServiceScopeFactory>();
|
||||
_mockScopeFactory.Setup(x => x.CreateScope()).Returns(_mockScope.Object);
|
||||
|
||||
var mockScriptResource = TestHelpers.CreateMockScriptResource();
|
||||
var mockConsoleHubContext = TestHelpers.CreateMockConsoleHubContext();
|
||||
var mockLoggerGlobals = TestHelpers.CreateMockLogger();
|
||||
var configuration = TestHelpers.CreateMockConfiguration();
|
||||
|
||||
_variableManager = new VariableManager();
|
||||
_taskManager = new TaskManager(
|
||||
_variableManager,
|
||||
mockScriptResource.Object,
|
||||
mockLoggerGlobals.Object,
|
||||
_mockScopeFactory.Object,
|
||||
mockConsoleHubContext.Object,
|
||||
configuration);
|
||||
_missionManager = new MissionManager(
|
||||
_mockScopeFactory.Object,
|
||||
_variableManager,
|
||||
mockScriptResource.Object,
|
||||
mockLoggerGlobals.Object,
|
||||
mockConsoleHubContext.Object,
|
||||
configuration);
|
||||
|
||||
_mockServiceProvider.Setup(x => x.GetRequiredService<MissionManager>()).Returns(_missionManager);
|
||||
_mockServiceProvider.Setup(x => x.GetRequiredService<TaskManager>()).Returns(_taskManager);
|
||||
|
||||
_scriptEngineGlobals = new ScriptEngineGlobals(_mockLogger.Object, _mockScopeFactory.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Logger_ShouldReturnProvidedLogger()
|
||||
{
|
||||
// Act
|
||||
var logger = _scriptEngineGlobals.Logger;
|
||||
|
||||
// Assert
|
||||
Assert.That(logger, Is.EqualTo(_mockLogger.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateMission_WithValidMission_ShouldReturnMissionId()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create<IAsyncEnumerable<MissionStatus>>(
|
||||
"yield return new MissionStatus(100, \"Success\");",
|
||||
ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
|
||||
var missionModel = new ScriptMissionModel(
|
||||
"TestMission",
|
||||
new List<ScriptMissionParameterModel>(),
|
||||
"code",
|
||||
100,
|
||||
false,
|
||||
false,
|
||||
runner);
|
||||
|
||||
_missionManager.Load([missionModel]);
|
||||
_missionManager.Start();
|
||||
|
||||
// Act
|
||||
var missionId = _scriptEngineGlobals.CreateMission("TestMission");
|
||||
|
||||
// Assert
|
||||
Assert.That(missionId, Is.Not.EqualTo(Guid.Empty));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateMission_WithNonExistentMission_ShouldThrowInvalidOperationException()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
_scriptEngineGlobals.CreateMission("NonExistentMission"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CancelMission_WithExistingMission_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create<IAsyncEnumerable<MissionStatus>>(
|
||||
"yield return new MissionStatus(100, \"Success\");",
|
||||
ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
|
||||
var missionModel = new ScriptMissionModel(
|
||||
"TestMission",
|
||||
new List<ScriptMissionParameterModel>(),
|
||||
"code",
|
||||
100,
|
||||
false,
|
||||
false,
|
||||
runner);
|
||||
|
||||
_missionManager.Load([missionModel]);
|
||||
_missionManager.Start();
|
||||
var missionId = _missionManager.CreateMission("TestMission", Array.Empty<object>()).Data;
|
||||
|
||||
// Act
|
||||
var result = _scriptEngineGlobals.CancelMission(missionId, "Test reason");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CancelMission_WithNonExistentMission_ShouldReturnFalse()
|
||||
{
|
||||
// Act
|
||||
var result = _scriptEngineGlobals.CancelMission(Guid.NewGuid(), "Test reason");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnableTask_WithExistingTask_ShouldSucceed()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create(
|
||||
"await Task.Delay(10);",
|
||||
ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
|
||||
var taskModel = new ScriptTaskModel(
|
||||
"TestTask",
|
||||
1000,
|
||||
false,
|
||||
"code",
|
||||
runner);
|
||||
|
||||
_taskManager.Load([taskModel]);
|
||||
_taskManager.Start();
|
||||
|
||||
// Act & Assert
|
||||
Assert.DoesNotThrow(() => _scriptEngineGlobals.EnableTask("TestTask"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnableTask_WithNonExistentTask_ShouldThrowInvalidOperationException()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
_scriptEngineGlobals.EnableTask("NonExistentTask"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisableTask_WithExistingTask_ShouldSucceed()
|
||||
{
|
||||
// Arrange
|
||||
var script = CSharpScript.Create(
|
||||
"await Task.Delay(10);",
|
||||
ScriptOptions.Default,
|
||||
typeof(ScriptGlobals));
|
||||
var runner = script.CreateDelegate();
|
||||
|
||||
var taskModel = new ScriptTaskModel(
|
||||
"TestTask",
|
||||
1000,
|
||||
false,
|
||||
"code",
|
||||
runner);
|
||||
|
||||
_taskManager.Load([taskModel]);
|
||||
_taskManager.Start();
|
||||
_taskManager.EnableTask("TestTask");
|
||||
|
||||
// Act & Assert
|
||||
Assert.DoesNotThrow(() => _scriptEngineGlobals.DisableTask("TestTask"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisableTask_WithNonExistentTask_ShouldThrowInvalidOperationException()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
_scriptEngineGlobals.DisableTask("NonExistentTask"));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_taskManager?.Dispose();
|
||||
_missionManager?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using RobotNet10.ScriptEngine;
|
||||
using RobotNet10.ScriptEngine.Enums;
|
||||
using RobotNet10.ScriptEngine.Helpers;
|
||||
using RobotNet10.ScriptEngine.Hubs;
|
||||
using RobotNet10.ScriptEngine.Models;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
using RobotNet10.ScriptEngine.Test.Helpers;
|
||||
using RobotNet10.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEngine.Test;
|
||||
|
||||
[TestFixture]
|
||||
public class ScriptEngineTests
|
||||
{
|
||||
private ScriptEngine _scriptEngine = null!;
|
||||
private Mock<IScriptEngineResource> _mockResource = null!;
|
||||
private FileManager _fileManager = null!;
|
||||
private VariableManager _variableManager = null!;
|
||||
private TaskManager _taskManager = null!;
|
||||
private MissionManager _missionManager = null!;
|
||||
private Mock<ILogger<ScriptEngine>> _mockLogger = null!;
|
||||
private Mock<IConfiguration> _mockConfiguration = null!;
|
||||
private Mock<IHubContext<ScriptManagerHub>> _mockHubContext = null!;
|
||||
private string _testScriptPath = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_testScriptPath = Path.Combine(Path.GetTempPath(), "ScriptEngineTest", Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(_testScriptPath);
|
||||
|
||||
_mockResource = TestHelpers.CreateMockScriptResource();
|
||||
_mockLogger = new Mock<ILogger<ScriptEngine>>();
|
||||
_mockConfiguration = new Mock<IConfiguration>();
|
||||
_mockHubContext = TestHelpers.CreateMockHubContext();
|
||||
|
||||
var mockConsoleHubContext = TestHelpers.CreateMockConsoleHubContext();
|
||||
var mockLoggerGlobals = TestHelpers.CreateMockLogger();
|
||||
var configuration = TestHelpers.CreateMockConfiguration();
|
||||
var mockScopeFactory = Mock.Of<IServiceScopeFactory>();
|
||||
|
||||
_variableManager = new VariableManager();
|
||||
_fileManager = new FileManager();
|
||||
_fileManager.RootPath = _testScriptPath;
|
||||
_taskManager = new TaskManager(
|
||||
_variableManager,
|
||||
_mockResource.Object,
|
||||
mockLoggerGlobals.Object,
|
||||
mockScopeFactory,
|
||||
mockConsoleHubContext.Object,
|
||||
configuration);
|
||||
_missionManager = new MissionManager(
|
||||
mockScopeFactory,
|
||||
_variableManager,
|
||||
_mockResource.Object,
|
||||
mockLoggerGlobals.Object,
|
||||
mockConsoleHubContext.Object,
|
||||
configuration);
|
||||
|
||||
_scriptEngine = new ScriptEngine(
|
||||
_mockResource.Object,
|
||||
_mockConfiguration.Object,
|
||||
_fileManager,
|
||||
_variableManager,
|
||||
_taskManager,
|
||||
_missionManager,
|
||||
_mockLogger.Object,
|
||||
_mockHubContext.Object,
|
||||
mockConsoleHubContext.Object);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_scriptEngine?.Dispose();
|
||||
_taskManager?.Dispose();
|
||||
_missionManager?.Dispose();
|
||||
|
||||
if (Directory.Exists(_testScriptPath))
|
||||
{
|
||||
Directory.Delete(_testScriptPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Constructor_ShouldInitializeToIdleState()
|
||||
{
|
||||
// Assert
|
||||
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Idle));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithValidScript_ShouldTransitionToReady()
|
||||
{
|
||||
// Arrange
|
||||
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
||||
File.WriteAllText(scriptFile, @"
|
||||
using RobotNet10.Script;
|
||||
|
||||
public class DummyClass
|
||||
{
|
||||
[Variable]
|
||||
public int TestVar = 42;
|
||||
}
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _scriptEngine.Build();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
// Wait a bit for async build to complete
|
||||
Thread.Sleep(500);
|
||||
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Ready).Or.EqualTo(ScriptEngineState.Building));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithInvalidScript_ShouldTransitionToBuildError()
|
||||
{
|
||||
// Arrange
|
||||
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
||||
File.WriteAllText(scriptFile, "invalid syntax here");
|
||||
|
||||
// Act
|
||||
var result = _scriptEngine.Build();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True); // Build initiation succeeds
|
||||
// Wait a bit for async build to complete
|
||||
Thread.Sleep(500);
|
||||
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.BuildError).Or.EqualTo(ScriptEngineState.Building));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WhenNotIdle_ShouldFail()
|
||||
{
|
||||
// Arrange
|
||||
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
||||
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
||||
_scriptEngine.Build();
|
||||
Thread.Sleep(500); // Wait for build to complete
|
||||
_scriptEngine.Start();
|
||||
Thread.Sleep(500); // Wait for start to complete
|
||||
|
||||
// Act
|
||||
var result = _scriptEngine.Build();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Start_WhenReady_ShouldTransitionToRunning()
|
||||
{
|
||||
// Arrange
|
||||
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
||||
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
||||
_scriptEngine.Build();
|
||||
Thread.Sleep(1000); // Wait for build to complete
|
||||
|
||||
// Act
|
||||
var result = _scriptEngine.Start();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Thread.Sleep(500);
|
||||
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Running).Or.EqualTo(ScriptEngineState.Starting));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Start_WhenNotReady_ShouldFail()
|
||||
{
|
||||
// Act
|
||||
var result = _scriptEngine.Start();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Stop_WhenRunning_ShouldTransitionToReady()
|
||||
{
|
||||
// Arrange
|
||||
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
||||
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
||||
_scriptEngine.Build();
|
||||
Thread.Sleep(1000);
|
||||
_scriptEngine.Start();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Act
|
||||
var result = _scriptEngine.Stop();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Thread.Sleep(2000); // Wait for stop to complete
|
||||
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Ready).Or.EqualTo(ScriptEngineState.Stopping));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Reset_ShouldTransitionToIdle()
|
||||
{
|
||||
// Arrange
|
||||
var scriptFile = Path.Combine(_testScriptPath, "test.cs");
|
||||
File.WriteAllText(scriptFile, "public class DummyClass { }");
|
||||
_scriptEngine.Build();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Act
|
||||
var result = _scriptEngine.Reset();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Thread.Sleep(500);
|
||||
Assert.That(_scriptEngine.State, Is.EqualTo(ScriptEngineState.Idle).Or.EqualTo(ScriptEngineState.Resetting));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Dispose_ShouldCleanupResources()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.DoesNotThrow(() => _scriptEngine.Dispose());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
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<IScriptEngineResource> _mockResource = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_variableManager = new VariableManager();
|
||||
_mockResource = TestHelpers.CreateMockScriptResource();
|
||||
var mockLogger = TestHelpers.CreateMockLogger();
|
||||
var mockScopeFactory = Mock.Of<IServiceScopeFactory>();
|
||||
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<ArgumentNullException>(() => _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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
using RobotNet10.ScriptEngine;
|
||||
using RobotNet10.ScriptEngine.Models;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEngine.Test;
|
||||
|
||||
[TestFixture]
|
||||
public class VariableManagerTests
|
||||
{
|
||||
private VariableManager _variableManager = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_variableManager = new VariableManager();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Load_WithValidVariables_ShouldLoadSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 42, true, true),
|
||||
new ScriptVariableModel("TestString", typeof(string), "Hello", true, false)
|
||||
};
|
||||
|
||||
// Act
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Assert
|
||||
Assert.That(_variableManager.HasVariable("TestInt"), Is.True);
|
||||
Assert.That(_variableManager.HasVariable("TestString"), Is.True);
|
||||
Assert.That(_variableManager.GetVariable<int>("TestInt"), Is.EqualTo(42));
|
||||
Assert.That(_variableManager.GetVariable<string>("TestString"), Is.EqualTo("Hello"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Load_WithNullVariables_ShouldThrowArgumentNullException()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentNullException>(() => _variableManager.Load(null!));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetVariable_WithExistingVariable_ShouldReturnValue()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 100, true, true)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Act
|
||||
var value = _variableManager.GetVariable<int>("TestInt");
|
||||
|
||||
// Assert
|
||||
Assert.That(value, Is.EqualTo(100));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetVariable_WithNonExistingVariable_ShouldReturnNull()
|
||||
{
|
||||
// Act
|
||||
var value = _variableManager.GetVariable("NonExisting");
|
||||
|
||||
// Assert
|
||||
Assert.That(value, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetVariable_WithPublicWriteVariable_ShouldSetSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 0, true, true)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Act
|
||||
var result = _variableManager.SetVariable("TestInt", 50);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.True);
|
||||
Assert.That(_variableManager.GetVariable<int>("TestInt"), Is.EqualTo(50));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetVariable_WithNonPublicWriteVariable_ShouldFail()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 0, true, false)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Act
|
||||
var result = _variableManager.SetVariable("TestInt", 50);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.False);
|
||||
Assert.That(_variableManager.GetVariable<int>("TestInt"), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_WithStringValue_ShouldConvertAndSet()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 0, true, true)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Act
|
||||
var result = _variableManager.SetValue("TestInt", "123");
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.True);
|
||||
Assert.That(_variableManager.GetVariable<int>("TestInt"), Is.EqualTo(123));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_WithNonWritableVariable_ShouldFail()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 0, true, false)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Act
|
||||
var result = _variableManager.SetValue("TestInt", "123");
|
||||
|
||||
// Assert
|
||||
Assert.That(result.IsSuccess, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetVariables_ShouldReturnPublicReadableVariables()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("PublicVar", typeof(int), 1, true, true),
|
||||
new ScriptVariableModel("PrivateVar", typeof(int), 2, false, false)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
|
||||
// Act
|
||||
var result = _variableManager.GetVariables().ToArray();
|
||||
|
||||
// Assert
|
||||
Assert.That(result.Length, Is.EqualTo(1));
|
||||
Assert.That(result[0].Name, Is.EqualTo("PublicVar"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Reset_ShouldClearAllVariables()
|
||||
{
|
||||
// Arrange
|
||||
var variables = new[]
|
||||
{
|
||||
new ScriptVariableModel("TestInt", typeof(int), 42, true, true)
|
||||
};
|
||||
_variableManager.Load(variables);
|
||||
Assert.That(_variableManager.HasVariable("TestInt"), Is.True);
|
||||
|
||||
// Act
|
||||
_variableManager.Reset();
|
||||
|
||||
// Assert
|
||||
Assert.That(_variableManager.HasVariable("TestInt"), Is.False);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user