nx_bills_store_gate.nx source
↩ module page · 83 lines · 4147 B
1// nx_bills_store_gate.nx -- proves the per-respondent BILL STORE: add bills -> they persist + round-trip,
2// they feed the nx_bills engine (overdue / monthly-total / per-category), and two people are isolated.
3// Hermetic /tmp prefix. Exits 0 iff ALL pass. license_tier: ORIGINAL
4import "nx_syscalls.nx"
5import "nx_money.nx"
6import "nx_bills.nx"
7import "nx_bills_store.nx"
8
9func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
10func g_putn(v: i64) -> i64 {
11 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
12 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
13 let d: *u8 = sys_mmap(24); var k: i64 = 0
14 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
15 var j: i64 = k - 1
16 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 }
17 return 0
18}
19func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 {
20 if got == want { st[0] = st[0] + 1; g_puts(" PASS "); g_puts(name); g_puts("\n") }
21 else { st[1] = st[1] + 1; g_puts(" FAIL "); g_puts(name); g_puts(" got="); g_putn(got); g_puts(" want="); g_putn(want); g_puts("\n") }
22 return 0
23}
24
25func main() -> i64 {
26 let st: *i64 = sys_mmap(16) as *i64
27 st[0] = 0; st[1] = 0
28
29 // hermetic prefix "/tmp/bills_<us>-"
30 let pfx: *u8 = sys_mmap(64)
31 var pp: i64 = 0
32 let pre: *u8 = "/tmp/bills_\x00" as *u8
33 while pre[pp] != (0 as u8) { pfx[pp] = pre[pp]; pp = pp + 1 }
34 let us: i64 = sys_now_us()
35 let tmp: *u8 = sys_mmap(32); var m: i64 = us; var kk: i64 = 0
36 if m == 0 { tmp[0] = 0x30 as u8; kk = 1 }
37 while m > 0 { tmp[kk] = (0x30 + (m % 10)) as u8; m = m / 10; kk = kk + 1 }
38 var z: i64 = kk - 1
39 while z >= 0 { pfx[pp] = tmp[z]; pp = pp + 1; z = z - 1 }
40 pfx[pp] = 0x2d as u8; pp = pp + 1; pfx[pp] = 0 as u8
41
42 let who: *u8 = "operator\x00" as *u8
43
44 // fresh: no bills
45 chk("fresh respondent -> 0 bills", bs_count(pfx, who), 0, st)
46
47 // add 3 real bills: insurance $1800/6mo due-15 unpaid; mortgage $2000/mo due-1 paid; utility $50/mo due-10 unpaid
48 chk("add insurance bill", bs_add(pfx, who, 180000, 6, 15, BL_INSURANCE, 0), 0, st)
49 chk("add mortgage bill", bs_add(pfx, who, 200000, 1, 1, BL_HOUSING, 1), 0, st)
50 chk("add utility bill", bs_add(pfx, who, 5000, 1, 10, BL_UTILITY, 0), 0, st)
51 chk("now 3 bills (persisted across reads)", bs_count(pfx, who), 3, st)
52
53 // load them back into the engine arrays
54 let amt: *i64 = sys_mmap(8 * 64) as *i64
55 let cad: *i64 = sys_mmap(8 * 64) as *i64
56 let due: *i64 = sys_mmap(8 * 64) as *i64
57 let cat: *i64 = sys_mmap(8 * 64) as *i64
58 let paid: *i64 = sys_mmap(8 * 64) as *i64
59 let n: i64 = bs_load(pfx, who, amt, cad, due, cat, paid, 64)
60 chk("load returns 3", n, 3, st)
61 // field round-trip (bill 0 = the insurance bill)
62 chk("bill0 amount = 180000c ($1800)", amt[0], 180000, st)
63 chk("bill0 cadence = 6 (semiannual)", cad[0], 6, st)
64 chk("bill0 due_day = 15", due[0], 15, st)
65 chk("bill0 category = INSURANCE", cat[0], BL_INSURANCE, st)
66 chk("bill0 paid = 0 (unpaid)", paid[0], 0, st)
67 chk("bill2 amount = 5000c ($50, the utility)", amt[2], 5000, st)
68
69 // the store FEEDS the engine: overdue today=20 -> insurance(15,unpaid) + utility(10,unpaid) = 2 (mortgage paid)
70 let oidx: *i64 = sys_mmap(8 * 64) as *i64
71 chk("engine overdue(today=20) over the REAL bills = 2", bl_overdue(due, paid, 20, n, oidx), 2, st)
72 // monthly total: $300 (insurance/6) + $2000 (mortgage) + $50 (utility) = $2350
73 chk("engine monthly total = 235000c ($2350)", bl_monthly_total(amt, cad, n), 235000, st)
74 chk("engine insurance monthly = 30000c ($300)", bl_category_monthly(amt, cad, cat, n, BL_INSURANCE), 30000, st)
75
76 // a different respondent is isolated (per-user)
77 chk("different respondent -> 0 bills (isolated)", bs_count(pfx, "someone_else\x00" as *u8), 0, st)
78
79 g_puts("nx_bills_store_gate: PASS="); g_putn(st[0]); g_puts(" FAIL="); g_putn(st[1]); g_puts("\n")
80 if st[1] == 0 { g_puts("SITUATION BILL-STORE: GREEN\n"); return 0 }
81 g_puts("SITUATION BILL-STORE: RED\n")
82 return 1
83}