@@ -180,15 +180,65 @@ async function main() {
180180 * the derivation) is invisible to any fixture whose names all start with `@`.
181181 */
182182
183+ // ── The self-test's own battery roster and floor (#13489) ──────────────────
184+ //
185+ // A `cases` list that holds a line per case, ok or FAIL, used to be this
186+ // self-test's ONLY success condition, so "every case held" and "the cases
187+ // never ran" printed the same line. Closed the way PR #13487 validated on
188+ // check-doc-authoring: what is pinned is the registered NAMES, not a
189+ // number. The floor requires the OPENED set to equal the DECLARED set with
190+ // each battery at or above its own count.
191+ //
192+ // This file declares ONE battery, opened at the top of the self-test body. It
193+ // carries fewer than the two named section banners the sectioning criterion
194+ // needs, and ⛔ a comment is NOT promoted to a section head — that is a
195+ // judgement per comment this transplant does not make. The hoisted single
196+ // battery is the shape PR #14896, PR #15003 and PR #15217 landed for exactly
197+ // this case.
198+ //
199+ // ⛔ A pinned TOTAL is not the repair: a battery dropping from 9 cases to 3
200+ // keeps a total "right" the moment a sibling grows.
201+ //
202+ // The count is a FLOOR, not an equality — adding cases is ordinary work and must
203+ // not red. A battery BELOW its floor means cases stopped running; the remedy is
204+ // to find what stopped registering.
205+ const SELF_TEST_BATTERIES = Object . freeze ( {
206+ 'publish-smoke-pack self-test' : 4 ,
207+ } ) ;
208+
209+ // DELETING an entry silences that battery's floor exactly as effectively as
210+ // zeroing it, so the roster's own size is pinned too.
211+ const SELF_TEST_BATTERY_FLOOR = 1 ;
212+
213+ // The key an assertion is filed under when no battery is open. It is not a
214+ // declared battery, so it reds by the same set difference rather than silently
215+ // inflating whichever battery happened to run last.
216+ const UNATTRIBUTED_BATTERY = '(no battery open)' ;
217+
183218// Returned by `selfTest()` only after its verdict is printed. The dispatch
184219// refuses anything else: a `return` that leaves the function above that line
185220// prints nothing and still exits 0 — a self-test that never finished, reported
186221// as one that passed (#13798).
187222const SELF_TEST_VERDICT = 'publish-smoke-pack self-test reached its verdict' ;
188223
189224function selfTest ( ) {
225+ // The battery ledger this self-test's floor is evaluated against (#13489).
226+ // `battery()` opens a battery; every assertion below is attributed to the one
227+ // most recently opened, so a section that stops running stops registering and
228+ // names ITSELF at the floor rather than going quiet.
229+ const batterySeen = new Map ( ) ;
230+ let openBattery = null ;
231+ const battery = ( name ) => {
232+ openBattery = name ;
233+ } ;
234+ const registerCase = ( ) => {
235+ const b = openBattery ?? UNATTRIBUTED_BATTERY ;
236+ batterySeen . set ( b , ( batterySeen . get ( b ) ?? 0 ) + 1 ) ;
237+ } ;
238+ battery ( 'publish-smoke-pack self-test' ) ;
190239 const cases = [ ] ;
191240 const check = ( name , fn ) => {
241+ registerCase ( ) ;
192242 try {
193243 fn ( ) ;
194244 cases . push ( ` ok — ${ name } ` ) ;
@@ -248,6 +298,56 @@ function selfTest() {
248298 assert ( msg . includes ( '@objectstack/gone' ) , `the diagnostic does not name the surplus package: ${ msg } ` ) ;
249299 } ) ;
250300
301+ // ── The floor: every declared battery RAN, and ran its cases (#13489) ────
302+ //
303+ // Evaluated after every battery has had its chance and BEFORE the verdict, so
304+ // the success line below can only be printed by a run in which the set of
305+ // batteries that registered assertions EQUALS the set declared. A set
306+ // difference names WHICH battery stopped; a count says only that something did.
307+ // The floor's refusal joins the SAME sink the cases use — a line in the
308+ // report and the failing exit code — so a breached floor reads exactly like a
309+ // failed case and cannot be printed over by the verdict below.
310+ const floorFailure = ( message ) => {
311+ cases . push ( ` FAIL — ${ message } ` ) ;
312+ process . exitCode = 1 ;
313+ } ;
314+ const declaredBatteries = Object . keys ( SELF_TEST_BATTERIES ) ;
315+ let floorBreached = false ;
316+ if ( declaredBatteries . length < SELF_TEST_BATTERY_FLOOR ) {
317+ floorBreached = true ;
318+ floorFailure (
319+ `SELF_TEST_BATTERIES declares ${ declaredBatteries . length } batteries, below the pinned `
320+ + `${ SELF_TEST_BATTERY_FLOOR } — a battery deleted from the roster takes its own floor with it.` ,
321+ ) ;
322+ }
323+ for ( const [ name , count ] of batterySeen ) {
324+ if ( declaredBatteries . includes ( name ) ) continue ;
325+ floorBreached = true ;
326+ floorFailure (
327+ `self-test battery "${ name } " registered ${ count } case(s) but is not declared in `
328+ + 'SELF_TEST_BATTERIES — an assertion attributed to no declared battery is one nothing floors.' ,
329+ ) ;
330+ }
331+ for ( const name of declaredBatteries ) {
332+ const count = batterySeen . get ( name ) ?? 0 ;
333+ if ( count >= SELF_TEST_BATTERIES [ name ] ) continue ;
334+ floorBreached = true ;
335+ floorFailure (
336+ count === 0
337+ ? `self-test battery "${ name } " DID NOT RUN — 0 cases registered, ${ SELF_TEST_BATTERIES [ name ] } pinned. `
338+ + 'The verdict below would have claimed those cases hold.'
339+ : `self-test battery "${ name } " registered ${ count } case(s), below its pinned floor of `
340+ + `${ SELF_TEST_BATTERIES [ name ] } — cases that used to run no longer do.` ,
341+ ) ;
342+ }
343+ if ( floorBreached ) {
344+ floorFailure (
345+ 'A battery at or below its floor means cases STOPPED RUNNING — the battery is the bug, not the '
346+ + 'number. Find what stopped registering (an early return, a deleted block, a guard that now '
347+ + 'skips) and restore it.' ,
348+ ) ;
349+ }
350+
251351 console . log ( 'publish-smoke-pack self-test' ) ;
252352 for ( const line of cases ) console . log ( line ) ;
253353 console . log ( process . exitCode === 1 ? 'SELF-TEST FAILED' : `SELF-TEST PASSED (${ cases . length } cases)` ) ;
0 commit comments