feat(scriptanalysis): M3.1 shared trust validator + compiler + compile surfaces + tests
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
using ZB.MOM.WW.ScadaBridge.ScriptAnalysis;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ScriptAnalysis.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// M3.1: parse + compile gate tests. The "representative real script" corpus is
|
||||
/// the PRIMARY guard that <see cref="ScriptCompileSurface"/> faithfully mirrors
|
||||
/// the runtime <c>ScriptGlobals</c> surface — if a member or signature drifts,
|
||||
/// the corpus stops binding and this test fails.
|
||||
/// </summary>
|
||||
public class RoslynScriptCompilerTests
|
||||
{
|
||||
[Fact]
|
||||
public void ParseDiagnostics_NonEmpty_ForSyntaxError()
|
||||
{
|
||||
Assert.NotEmpty(RoslynScriptCompiler.ParseDiagnostics("var x = ;"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseDiagnostics_Empty_ForValidSyntax()
|
||||
{
|
||||
Assert.Empty(RoslynScriptCompiler.ParseDiagnostics("var x = 1;"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Compile_NonEmpty_ForUndefinedSymbol()
|
||||
{
|
||||
var code = "var x = NoSuchThing.Foo();";
|
||||
Assert.NotEmpty(RoslynScriptCompiler.Compile(code, typeof(ScriptCompileSurface)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Compile_Empty_ForRepresentativeRealScript()
|
||||
{
|
||||
const string code = """
|
||||
var temp = Attributes["Temperature"];
|
||||
Attributes["Setpoint"] = 42;
|
||||
var r = await ExternalSystem.Call("erp", "sync");
|
||||
var op = await Database.CachedWrite("hist", "INSERT ...");
|
||||
await Notify.To("ops").Send("subj", "msg");
|
||||
var shared = await Scripts.CallShared("Helper");
|
||||
var child = Children["Pump"].Attributes["Speed"];
|
||||
|
||||
// Widen coverage across the rest of the surface.
|
||||
var attr = await Instance.GetAttribute("Temperature");
|
||||
await Instance.SetAttribute("Setpoint", "43");
|
||||
var track = await Instance.Tracking.Status(op);
|
||||
var parentSpeed = Parent?.Attributes["Speed"];
|
||||
var alarmName = Alarm?.Name;
|
||||
var p = Parameters;
|
||||
var ct = CancellationToken;
|
||||
var status = await Notify.Status("notif-id");
|
||||
var cachedCall = await ExternalSystem.CachedCall("erp", "ping");
|
||||
var resolved = Attributes.Resolve("Temperature");
|
||||
var conn = await Database.Connection("hist");
|
||||
var scope = Scope;
|
||||
""";
|
||||
|
||||
var diagnostics = RoslynScriptCompiler.Compile(code, typeof(ScriptCompileSurface));
|
||||
Assert.Empty(diagnostics);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Compile_Empty_ForTriggerExpression()
|
||||
{
|
||||
const string expr =
|
||||
"Attributes[\"Temp\"] != null && (int)(Children[\"P\"].Attributes[\"S\"] ?? 0) > 5";
|
||||
|
||||
var diagnostics = RoslynScriptCompiler.Compile(expr, typeof(TriggerCompileSurface));
|
||||
Assert.Empty(diagnostics);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user