@@ -274,3 +274,52 @@ test('parseMinerDetail: well-formed input produces typed output', () => {
274274 }
275275 } ) , { numRuns : 300 } ) ;
276276} ) ;
277+
278+ // ── Regression: non-finite numbers (Infinity / -Infinity / NaN) ──────
279+ // Pinned counterexamples for the fast-check flake on PRs #49/#50
280+ // (seed -1679627146, shrunk input [Infinity]). A bare Infinity in the
281+ // legacy flat-map shape was assigned to amount without finite filtering,
282+ // so it survived the amount > 0 guard and poisoned totalPrimary. These
283+ // explicit cases lock the three non-finite shapes regardless of seed.
284+
285+ test ( 'parseSnapshot: non-finite amounts are dropped, total stays finite' , ( ) => {
286+ // Array shape: Object.entries([x]) -> ["0", x], hits the legacy
287+ // bare-number branch — the exact path the property test shrank to.
288+ for ( const raw of [ [ Infinity ] , [ - Infinity ] , [ NaN ] ] ) {
289+ const snap = parseSnapshot ( raw ) ;
290+ assert . ok ( Number . isFinite ( snap . totalPrimary ) ,
291+ `totalPrimary not finite for ${ String ( raw [ 0 ] ) } ` ) ;
292+ assert . equal ( snap . totalPrimary , 0 ) ;
293+ assert . equal ( snap . miners . length , 0 ) ;
294+ // Required-keys contract (mirrors the property assertions at L107-112).
295+ assert . equal ( typeof snap . totalPrimary , 'number' ) ;
296+ assert . ok ( Array . isArray ( snap . mergedChains ) ) ;
297+ assert . ok ( snap . mergedTotals !== null && typeof snap . mergedTotals === 'object' ) ;
298+ assert . equal ( typeof snap . schemaVersion , 'string' ) ;
299+ assert . ok ( Array . isArray ( snap . miners ) ) ;
300+ }
301+ } ) ;
302+
303+ test ( 'parseSnapshot: non-finite legacy-object amounts are dropped' , ( ) => {
304+ // Legacy { addr: { amount } } shape with a non-finite amount field.
305+ for ( const bad of [ Infinity , - Infinity , NaN ] ) {
306+ const snap = parseSnapshot ( { miner1 : { amount : bad } } ) ;
307+ assert . ok ( Number . isFinite ( snap . totalPrimary ) ) ;
308+ assert . equal ( snap . totalPrimary , 0 ) ;
309+ assert . equal ( snap . miners . length , 0 ) ;
310+ }
311+ } ) ;
312+
313+ test ( 'parseSnapshot: non-finite new-shape miner amounts are dropped' , ( ) => {
314+ // New shape: a miner row whose amount is non-finite must not appear
315+ // and must not poison the totalPrimary fallback sum.
316+ for ( const bad of [ Infinity , - Infinity , NaN ] ) {
317+ const snap = parseSnapshot ( {
318+ total_primary : 0 ,
319+ miners : [ { address : 'a' , amount : bad , pct : 0 } ] ,
320+ } ) ;
321+ assert . ok ( Number . isFinite ( snap . totalPrimary ) ) ;
322+ assert . equal ( snap . totalPrimary , 0 ) ;
323+ assert . equal ( snap . miners . length , 0 ) ;
324+ }
325+ } ) ;
0 commit comments