nx_shelf_life_test.nx source
↩ module page · 41 lines · 1862 B
1// nx_shelf_life_test.nx -- smoke for nx_shelf_life. Proves the Q10 shelf-
2// life model (decade-exact), the honest non-decade gap, and the cold-chain
3// breach accumulator. Exit code = failed assertion number; 0 = all pass.
4
5import "nx_syscalls.nx"
6import "nx_shelf_life.nx"
7
8func main() -> i64 {
9 // --- Q10 powers ---
10 if sl_q10_pow(2, 3) != 8 { return 1 }
11 if sl_q10_pow(3, 2) != 9 { return 2 }
12
13 // --- shelf life vs temperature (100 days at 4 C, Q10 = 2) ---
14 if sl_at_temp(100, 4, 2, 4) != 100 { return 3 } // reference
15 if sl_at_temp(100, 4, 2, 14) != 50 { return 4 } // 10 C warmer -> half
16 if sl_at_temp(100, 4, 2, 24) != 25 { return 5 } // 20 C warmer -> quarter
17 if sl_at_temp(100, 4, 2, 0 - 6) != 200 { return 6 } // 10 C colder -> double
18 // Q10 = 3 case
19 if sl_at_temp(90, 20, 3, 30) != 30 { return 7 }
20
21 // --- honest gap: a non-decade temperature needs a fractional power ---
22 if sl_at_temp(100, 4, 2, 10) != 0 - 1 { return 8 }
23
24 // --- life consumed + expiry ---
25 if sl_life_consumed_milli(25, 50) != 500 { return 9 } // half used
26 if sl_is_expired(500) != 0 { return 10 }
27 if sl_is_expired(1000) != 1 { return 11 }
28 if sl_remaining_milli(400) != 600 { return 12 }
29
30 // --- COLD-CHAIN accumulation: 20 d @4 C + 10 d @14 C = 40% used, OK;
31 // a 30 d @24 C breach pushes it over 1.000 -> expired ---
32 var consumed: i64 = 0
33 consumed = consumed + sl_life_consumed_milli(20, sl_at_temp(100, 4, 2, 4)) // 20/100 = 200
34 consumed = consumed + sl_life_consumed_milli(10, sl_at_temp(100, 4, 2, 14)) // 10/50 = 200
35 if consumed != 400 { return 13 }
36 if sl_is_expired(consumed) != 0 { return 14 }
37 consumed = consumed + sl_life_consumed_milli(30, sl_at_temp(100, 4, 2, 24)) // 30/25 = 1200
38 if sl_is_expired(consumed) != 1 { return 15 }
39
40 return 0
41}