using ScadaLink.TemplateEngine.Validation; namespace ScadaLink.TemplateEngine.Tests.Validation; public class ScriptCompilerTests { private readonly ScriptCompiler _sut = new(); [Fact] public void TryCompile_ValidCode_ReturnsSuccess() { var result = _sut.TryCompile("var x = 1; if (x > 0) { x++; }", "Test"); Assert.True(result.IsSuccess); } [Fact] public void TryCompile_EmptyCode_ReturnsFailure() { var result = _sut.TryCompile("", "Test"); Assert.True(result.IsFailure); Assert.Contains("empty", result.Error, StringComparison.OrdinalIgnoreCase); } [Fact] public void TryCompile_MismatchedBraces_ReturnsFailure() { var result = _sut.TryCompile("if (true) { x = 1;", "Test"); Assert.True(result.IsFailure); Assert.Contains("braces", result.Error, StringComparison.OrdinalIgnoreCase); } [Fact] public void TryCompile_UnclosedBlockComment_ReturnsFailure() { var result = _sut.TryCompile("/* this is never closed", "Test"); Assert.True(result.IsFailure); Assert.Contains("comment", result.Error, StringComparison.OrdinalIgnoreCase); } [Theory] [InlineData("System.IO.File.ReadAllText(\"x\");")] [InlineData("System.Diagnostics.Process.Start(\"cmd\");")] [InlineData("System.Threading.Thread.Sleep(1000);")] [InlineData("System.Reflection.Assembly.Load(\"x\");")] [InlineData("System.Net.Sockets.TcpClient c;")] [InlineData("System.Net.Http.HttpClient c;")] public void TryCompile_ForbiddenApi_ReturnsFailure(string code) { var result = _sut.TryCompile(code, "Test"); Assert.True(result.IsFailure); Assert.Contains("forbidden", result.Error, StringComparison.OrdinalIgnoreCase); } [Fact] public void TryCompile_BracesInStrings_Ignored() { var result = _sut.TryCompile("var s = \"{ not a brace }\";", "Test"); Assert.True(result.IsSuccess); } [Fact] public void TryCompile_BracesInComments_Ignored() { var result = _sut.TryCompile("// { not a brace\nvar x = 1;", "Test"); Assert.True(result.IsSuccess); } [Fact] public void TryCompile_BlockCommentWithBraces_Ignored() { var result = _sut.TryCompile("/* { } */ var x = 1;", "Test"); Assert.True(result.IsSuccess); } }