Skip to content

Commit be70d4b

Browse files
authored
Fix PR #180 main-side CI regressions: Octave + MATLAB E-I (#181)
Octave Tests: make NotificationCenterPane.m Octave-loadable (drop logical type-constraint, Event.empty -> [], replace object-array comma-list/arrayfun with explicit loops). MATLAB Tests (E-I): update TestFastSenseCompanionPlantLogToolbar to the shipped 1x10 toolbar layout after the Phase 1040 bell. Test-only + compat; verified 18/18 in Octave+MATLAB and 11/11 toolbar in MATLAB.
1 parent 2a191c0 commit be70d4b

4 files changed

Lines changed: 58 additions & 34 deletions

File tree

libs/FastSenseCompanion/NotificationCenterPane.m

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
end
3636

3737
properties (SetAccess = private)
38-
IsAttached logical = false
38+
IsAttached = false % logical flag (no type-constraint syntax — Octave-incompatible)
3939
end
4040

4141
properties (Access = private)
@@ -48,7 +48,7 @@
4848
hLastUpdateLbl_ = [] % "Updated: HH:MM:SS" label
4949
hPopoutBtn_ = [] % pop-out icon uibutton
5050
Companion_ = [] % FastSenseCompanion handle (or [])
51-
LastGoodEvents_ = Event.empty % last successfully-read unacked set (survives detach)
51+
LastGoodEvents_ = [] % last successfully-read unacked set (survives detach)
5252
LastIds_ = {} % cellstr of LastGoodEvents_ ids (diff key)
5353
Listeners_ = {} % addlistener handles; deleted on teardown
5454
IsStale_ = false % true when the last EventStore read failed
@@ -69,7 +69,7 @@
6969
end
7070
obj.ThemeStruct_ = themeStruct;
7171
obj.IsAttached = false;
72-
obj.LastGoodEvents_ = Event.empty;
72+
obj.LastGoodEvents_ = [];
7373
obj.LastIds_ = {};
7474
obj.Listeners_ = {};
7575
obj.IsStale_ = false;
@@ -232,14 +232,14 @@ function refresh(obj, eventStore)
232232
% (stale) marker; never clear the inbox and never uialert.
233233
if ~obj.IsAttached; return; end
234234
if isempty(eventStore) || ~isvalid(eventStore)
235-
obj.LastGoodEvents_ = Event.empty;
235+
obj.LastGoodEvents_ = [];
236236
obj.LastIds_ = {};
237237
obj.IsStale_ = false;
238238
obj.applyFilterAndRender_();
239239
obj.setUpdatedLabel_(datetime('now'), false);
240240
return;
241241
end
242-
allEvents = Event.empty;
242+
allEvents = [];
243243
readOk = true;
244244
try
245245
allEvents = eventStore.getEvents();
@@ -353,7 +353,13 @@ function applyFilterAndRender_(obj)
353353
otherwise, wanted = [];
354354
end
355355
if ~isempty(wanted)
356-
events = events([events.Severity] == wanted);
356+
% Explicit loop (Octave can't comma-list-expand [events.Severity]
357+
% over a classdef object array) — mirrors the text filter below.
358+
sevMask = false(1, numel(events));
359+
for i = 1:numel(events)
360+
sevMask(i) = (events(i).Severity == wanted);
361+
end
362+
events = events(sevMask);
357363
end
358364
end
359365
% Free-text filter over SensorName + ThresholdLabel (case-insensitive).
@@ -640,7 +646,7 @@ function ackForTest_(obj, eventId)
640646
% An event is unacked iff AckedAt is empty OR all-NaN (mirrors
641647
% Event.computeDisplayState). Empty input returns an empty Event array.
642648
if isempty(allEvents)
643-
evs = Event.empty;
649+
evs = [];
644650
return;
645651
end
646652
mask = false(1, numel(allEvents));
@@ -654,7 +660,13 @@ function ackForTest_(obj, eventId)
654660
function evs = sortNewestFirst_(events)
655661
%SORTNEWESTFIRST_ Order events by StartTime, newest first.
656662
if numel(events) > 1
657-
[~, ord] = sort([events.StartTime], 'descend');
663+
% Explicit loop (Octave can't comma-list-expand [events.StartTime]
664+
% over a classdef object array).
665+
starts = zeros(1, numel(events));
666+
for i = 1:numel(events)
667+
starts(i) = events(i).StartTime;
668+
end
669+
[~, ord] = sort(starts, 'descend');
658670
evs = events(ord);
659671
else
660672
evs = events;
@@ -666,7 +678,12 @@ function ackForTest_(obj, eventId)
666678
if isempty(events)
667679
s = 0;
668680
else
669-
s = max([events.Severity]);
681+
% Explicit loop (Octave can't comma-list-expand [events.Severity]).
682+
sevs = zeros(1, numel(events));
683+
for i = 1:numel(events)
684+
sevs(i) = events(i).Severity;
685+
end
686+
s = max(sevs);
670687
end
671688
end
672689

@@ -675,7 +692,11 @@ function ackForTest_(obj, eventId)
675692
if isempty(events)
676693
ids = {};
677694
else
678-
ids = arrayfun(@(e) e.Id, events, 'UniformOutput', false);
695+
% Explicit loop (Octave can't arrayfun over a classdef object array).
696+
ids = cell(1, numel(events));
697+
for i = 1:numel(events)
698+
ids{i} = events(i).Id;
699+
end
679700
end
680701
end
681702

tests/StubEventStore.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
% See also EventStore, Event, NotificationCenterPane, CaptureNotificationService.
2323

2424
properties
25-
Events_ = Event.empty % Event array; configure in test setup
25+
Events_ = [] % Event array (configure in test setup); [] not Event.empty for Octave parity
2626
AckedIds_ = {} % cellstr: each eventId passed to acknowledgeEvent, in call order
2727
ThrowOnAck_ = false % when true, acknowledgeEvent throws EventStore:unknownEventId
2828
ThrowOnGet_ = false % when true, getEvents throws (exercises the stale path)

tests/suite/TestFastSenseCompanionPlantLogToolbar.m

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,20 @@ function cleanupAll(testCase)
114114
end
115115

116116
function g = findToolbarGrid_(testCase, c) %#ok<INUSL>
117-
% After v3.1 Plant Log + v4.0 Wiki Browser merges, the
118-
% Companion toolbar is a 1x9 grid:
119-
% {110, 110, 110, 130, 70, 90, 70, '1x', 36}
117+
% After v3.1 Plant Log + v4.0 Wiki Browser + v4.0 Phase 1040
118+
% notification bell, the Companion toolbar is a 1x10 grid:
119+
% {110, 110, 110, 130, 70, 90, 70, 70, '1x', 36}
120120
fig = c.getFigForTest_();
121121
grids = findobj(fig, 'Type', 'uigridlayout');
122122
g = [];
123123
for i = 1:numel(grids)
124-
if numel(grids(i).ColumnWidth) == 9
124+
if numel(grids(i).ColumnWidth) == 10
125125
cw = grids(i).ColumnWidth;
126126
if iscell(cw) && isequal(cw{1}, 110) && isequal(cw{2}, 110) && ...
127127
isequal(cw{3}, 110) && isequal(cw{4}, 130) && ...
128128
isequal(cw{5}, 70) && isequal(cw{6}, 90) && ...
129-
isequal(cw{7}, 70) && isequal(cw{9}, 36)
129+
isequal(cw{7}, 70) && isequal(cw{8}, 70) && ...
130+
isequal(cw{10}, 36)
130131
g = grids(i);
131132
return;
132133
end
@@ -139,22 +140,23 @@ function cleanupAll(testCase)
139140
methods (Test)
140141

141142
function testToolbarGridIs1x5(testCase)
142-
% v3.1 Plant Log + v4.0 Wiki Browser merged: toolbar grew from
143-
% 1x4 to 1x9.
144-
% col 1 = Events (110)
145-
% col 2 = Live (110)
146-
% col 3 = Tags (110, v4.0 quick task 260519-bs4)
147-
% col 4 = Plant Log (130, v3.1 Phase 1033 PLOG-INT-03)
148-
% col 5 = Tile ( 70, v4.0 S0Y-01)
149-
% col 6 = Close all ( 90, v4.0 S0Y-02)
150-
% col 7 = Wiki ( 70, v4.0 Phase 1034)
151-
% col 8 = flex spacer
152-
% col 9 = gear ( 36)
143+
% v3.1 Plant Log + v4.0 Wiki Browser + Phase 1040 bell: toolbar
144+
% grew from 1x4 to 1x10.
145+
% col 1 = Events (110)
146+
% col 2 = Live (110)
147+
% col 3 = Tags (110, v4.0 quick task 260519-bs4)
148+
% col 4 = Plant Log (130, v3.1 Phase 1033 PLOG-INT-03)
149+
% col 5 = Tile ( 70, v4.0 S0Y-01)
150+
% col 6 = Close all ( 90, v4.0 S0Y-02)
151+
% col 7 = Wiki ( 70, v4.0 Phase 1034)
152+
% col 8 = Bell ( 70, v4.0 Phase 1040 notification center)
153+
% col 9 = flex spacer
154+
% col 10 = gear ( 36)
153155
d1 = testCase.makeEngine_('A');
154156
c = testCase.makeCompanion_({d1});
155157
g = testCase.findToolbarGrid_(c);
156158
testCase.verifyNotEmpty(g, ...
157-
'toolbar grid (1x8 with ColumnWidth {110 110 110 130 70 90 ''1x'' 36}) must exist');
159+
'toolbar grid (1x10 with ColumnWidth {110 110 110 130 70 90 70 70 ''1x'' 36}) must exist');
158160
cw = g.ColumnWidth;
159161
testCase.verifyEqual(cw{1}, 110, 'ColumnWidth{1} (Events)');
160162
testCase.verifyEqual(cw{2}, 110, 'ColumnWidth{2} (Live)');
@@ -163,8 +165,9 @@ function testToolbarGridIs1x5(testCase)
163165
testCase.verifyEqual(cw{5}, 70, 'ColumnWidth{5} (Tile, v4.0)');
164166
testCase.verifyEqual(cw{6}, 90, 'ColumnWidth{6} (Close all, v4.0)');
165167
testCase.verifyEqual(cw{7}, 70, 'ColumnWidth{7} (Wiki, v4.0 Phase 1034)');
166-
testCase.verifyEqual(cw{8}, '1x', 'ColumnWidth{8} flex spacer');
167-
testCase.verifyEqual(cw{9}, 36, 'ColumnWidth{9} (gear)');
168+
testCase.verifyEqual(cw{8}, 70, 'ColumnWidth{8} (Bell, v4.0 Phase 1040)');
169+
testCase.verifyEqual(cw{9}, '1x', 'ColumnWidth{9} flex spacer');
170+
testCase.verifyEqual(cw{10}, 36, 'ColumnWidth{10} (gear)');
168171
end
169172

170173
function testPlantLogButtonExists(testCase)
@@ -211,13 +214,13 @@ function testPlantLogButtonDisabledWithoutDashboards(testCase)
211214
end
212215

213216
function testSettingsButtonMovedToCol5(testCase)
214-
% After v3.1 + v4.0 merge, gear lives at col 8 (1x8 grid).
217+
% After v3.1 + v4.0 + Phase 1040 bell, gear lives at col 10 (1x10 grid).
215218
d1 = testCase.makeEngine_('A');
216219
c = testCase.makeCompanion_({d1});
217220
gear = findobj(c.getFigForTest_(), 'Tooltip', 'Companion settings');
218221
testCase.verifyNotEmpty(gear);
219-
testCase.verifyEqual(gear.Layout.Column, 9, ...
220-
'settings gear must be at col 9 (1x9 grid post-v3.1+Wiki-Browser merge)');
222+
testCase.verifyEqual(gear.Layout.Column, 10, ...
223+
'settings gear must be at col 10 (1x10 grid post-Phase-1040 bell)');
221224
end
222225

223226
function testFindObjResolvesViaTag(testCase)

tests/test_notification_center_pane.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function test_notification_center_pane()
4343

4444
% 4. maxSeverity_.
4545
n = n + 1; check(NotificationCenterPane.maxSeverity_([e1 e2]) == 3, 'maxSeverity_([3 2]) should be 3');
46-
n = n + 1; check(NotificationCenterPane.maxSeverity_(Event.empty) == 0, 'maxSeverity_(empty) should be 0');
46+
n = n + 1; check(NotificationCenterPane.maxSeverity_([]) == 0, 'maxSeverity_(empty) should be 0');
4747

4848
% 5. diffIds_ — order-insensitive set comparison.
4949
n = n + 1; check(~NotificationCenterPane.diffIds_({'a', 'b'}, {'b', 'a'}), ...

0 commit comments

Comments
 (0)