feat(scripts): ScriptAlarm.IsMesReportable + Alarms.MesReportableAsync() mirrored on both compile surfaces
Claude-Session: https://claude.ai/code/session_01Y5ef34iUUMjmwnMpL9xgmB
This commit is contained in:
+3
-1
@@ -819,7 +819,9 @@ public class ScriptAnalysisServiceTests
|
||||
" AckDT = a.AckTime,\n" +
|
||||
" AckComment = a.OperatorComment })\n" +
|
||||
" .ToList();\n" +
|
||||
"return new { WasSuccessful = true, Alarms = rows };";
|
||||
"var r = await Alarms.MesReportableAsync();\n" +
|
||||
"var f = r.Where(a => a.IsMesReportable).ToList();\n" +
|
||||
"return new { WasSuccessful = true, Alarms = rows, Flagged = f.Count };";
|
||||
var resp = _svc.Diagnose(new DiagnoseRequest(code));
|
||||
|
||||
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("CS"));
|
||||
|
||||
@@ -56,6 +56,8 @@ public class RoslynScriptCompilerTests
|
||||
var scope = Scope;
|
||||
var currentAlarms = await Alarms.CurrentAsync();
|
||||
var viaInstance = await Instance.Alarms.CurrentAsync();
|
||||
var mesReportable = await Alarms.MesReportableAsync();
|
||||
var flaggedAlarms = mesReportable.Where(a => a.IsMesReportable).ToList();
|
||||
""";
|
||||
|
||||
var diagnostics = RoslynScriptCompiler.Compile(code, typeof(ScriptCompileSurface));
|
||||
@@ -101,7 +103,12 @@ public class RoslynScriptCompilerTests
|
||||
AckComment = a.OperatorComment,
|
||||
}).ToList();
|
||||
|
||||
return new { WasSuccessful = true, ErrorText = (string)null, Alarms = infos };
|
||||
// The pre-filtered accessor + the configured flag are the supported shape for
|
||||
// "which alarms does MES care about?" — both must bind at design time.
|
||||
var r = await Alarms.MesReportableAsync();
|
||||
var f = r.Where(a => a.IsMesReportable).ToList();
|
||||
|
||||
return new { WasSuccessful = true, ErrorText = (string)null, Alarms = infos, Flagged = f.Count };
|
||||
""";
|
||||
|
||||
Assert.Empty(RoslynScriptCompiler.Compile(code, typeof(ScriptCompileSurface)));
|
||||
|
||||
@@ -187,6 +187,43 @@ public class AlarmsAccessorTests : TestKit, IDisposable
|
||||
Assert.Equal("Z28061.HeartbeatTimeoutAlarm", real.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CurrentAsync_ProjectsIsMesReportable()
|
||||
{
|
||||
// The deployed configuration's MES-reportable flag rides the snapshot row and must
|
||||
// reach the script projection verbatim — a row without it reads false.
|
||||
var probe = CreateTestProbe();
|
||||
var ctx = MakeContext(probe.Ref);
|
||||
|
||||
var pending = ctx.Alarms.CurrentAsync();
|
||||
RespondWith(probe,
|
||||
NativeAcked() with { IsMesReportable = true },
|
||||
new AlarmStateChanged("CvdReactor01", "HighTemp", AlarmState.Active, 700, ObservedAt));
|
||||
|
||||
var alarms = await pending;
|
||||
Assert.Equal(2, alarms.Count);
|
||||
Assert.True(Assert.Single(alarms, a => a.Name == "Z28061.HeartbeatTimeoutAlarm").IsMesReportable);
|
||||
Assert.False(Assert.Single(alarms, a => a.Name == "HighTemp").IsMesReportable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MesReportableAsync_FiltersToFlaggedRows()
|
||||
{
|
||||
// The convenience accessor is CurrentAsync restricted to the flagged subset, so a
|
||||
// script does not have to repeat the filter (and cannot get it subtly wrong).
|
||||
var probe = CreateTestProbe();
|
||||
var ctx = MakeContext(probe.Ref);
|
||||
|
||||
var pending = ctx.Alarms.MesReportableAsync();
|
||||
RespondWith(probe,
|
||||
NativeAcked() with { IsMesReportable = true },
|
||||
NativeAcked() with { AlarmName = "Z28061.UnflaggedAlarm", SourceReference = "Z28061.UnflaggedAlarm" });
|
||||
|
||||
var alarm = Assert.Single(await pending);
|
||||
Assert.Equal("Z28061.HeartbeatTimeoutAlarm", alarm.Name);
|
||||
Assert.True(alarm.IsMesReportable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CurrentAsync_IsNotScopePrefixed_EveryScopeSeesTheSameList()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user