nx_chem_report_json_test.nx source
↩ module page · 248 lines · 11700 B
1// nx_chem_report_json_test.nx -- C6.0 KAT + end-to-end JSON demo.
2//
3// Validates JSON emitter primitives + complete report assembly +
4// dumps a real LIMS-ingestion-ready report to stdout for visual check.
5//
6// expect_exit: 0
7// license_tier: ORIGINAL
8
9import "nx_chem.nx"
10import "nx_chem_molecule.nx"
11import "nx_chem_smiles.nx"
12import "nx_chem_periodic.nx"
13import "nx_chem_valence.nx"
14import "nx_chem_mass.nx"
15import "nx_chem_isotope_pattern.nx"
16import "nx_chem_adulterant_db.nx"
17import "nx_chem_peak_list.nx"
18import "nx_chem_report_json.nx"
19
20// =================================================================
21// A -- emit_str copies bytes correctly
22// =================================================================
23func a_emit_str() -> nx_int {
24 let buf: *u8 = sys_mmap(64)
25 let n: nx_int = nx_chem_emit_str(buf, 0, "hello" as *u8)
26 if n != 5 { return 11 }
27 if buf[0] as nx_int != 0x68 { return 12 } // 'h'
28 if buf[4] as nx_int != 0x6F { return 13 } // 'o'
29 return 0
30}
31
32// =================================================================
33// B -- emit_str_escaped wraps in quotes + escapes internal "
34// =================================================================
35func b_emit_str_escaped_quote() -> nx_int {
36 let buf: *u8 = sys_mmap(64)
37 // Source with embedded quote: hello"world
38 let src: *u8 = sys_mmap(32)
39 src[0] = 0x68; src[1] = 0x65; src[2] = 0x6C; src[3] = 0x6C; src[4] = 0x6F
40 src[5] = 0x22 // "
41 src[6] = 0x77; src[7] = 0x6F; src[8] = 0x72; src[9] = 0x6C; src[10] = 0x64
42 src[11] = 0
43 let n: nx_int = nx_chem_emit_str_escaped(buf, 0, src)
44 // Expected: "hello\"world" (14 bytes: " h e l l o \ " w o r l d ")
45 if buf[0] as nx_int != 0x22 { return 21 } // opening "
46 if buf[5] as nx_int != 0x6F { return 22 } // 'o' (end of hello)
47 if buf[6] as nx_int != 0x5C { return 23 } // \ (escape)
48 if buf[7] as nx_int != 0x22 { return 24 } // escaped "
49 if n != 14 { return 25 } // 11 chars + 2 quotes + 1 escape
50 return 0
51}
52
53// =================================================================
54// C -- emit_int handles common values
55// =================================================================
56func c_emit_int() -> nx_int {
57 let buf: *u8 = sys_mmap(32)
58 // 0
59 let n0: nx_int = nx_chem_emit_int(buf, 0, 0)
60 if n0 != 1 { return 31 }
61 if buf[0] as nx_int != 0x30 { return 32 }
62 // 123
63 let n1: nx_int = nx_chem_emit_int(buf, 5, 123)
64 if n1 != 3 { return 33 }
65 if buf[5] as nx_int != 0x31 { return 34 }
66 if buf[6] as nx_int != 0x32 { return 35 }
67 if buf[7] as nx_int != 0x33 { return 36 }
68 // -42
69 let n2: nx_int = nx_chem_emit_int(buf, 10, -42)
70 if n2 != 3 { return 37 }
71 if buf[10] as nx_int != 0x2D { return 38 }
72 if buf[11] as nx_int != 0x34 { return 39 }
73 return 0
74}
75
76// =================================================================
77// D -- emit_q4 formats decimal correctly
78// =================================================================
79func d_emit_q4() -> nx_int {
80 let buf: *u8 = sys_mmap(32)
81 // 280.1826 -> "280.1826"
82 let n: nx_int = nx_chem_emit_q4(buf, 0, 2801826)
83 if n != 8 { return 41 }
84 if buf[0] as nx_int != 0x32 { return 42 } // '2'
85 if buf[3] as nx_int != 0x2E { return 43 } // '.'
86 if buf[7] as nx_int != 0x36 { return 44 } // '6'
87 return 0
88}
89
90// =================================================================
91// E -- emit_q4 zero-pads short fractionals: 12.0050 should output "12.0050"
92// =================================================================
93func e_emit_q4_padded() -> nx_int {
94 let buf: *u8 = sys_mmap(32)
95 let n: nx_int = nx_chem_emit_q4(buf, 0, 120050)
96 if n != 7 { return 51 }
97 if buf[3] as nx_int != 0x30 { return 52 } // leading 0 in frac
98 return 0
99}
100
101// =================================================================
102// F -- buf_find locates substring correctly
103// =================================================================
104func f_buf_find() -> nx_int {
105 let hay: *u8 = sys_mmap(32)
106 // "hello world"
107 hay[0] = 0x68; hay[1] = 0x65; hay[2] = 0x6C; hay[3] = 0x6C; hay[4] = 0x6F
108 hay[5] = 0x20
109 hay[6] = 0x77; hay[7] = 0x6F; hay[8] = 0x72; hay[9] = 0x6C; hay[10] = 0x64
110 let off1: nx_int = nx_chem_buf_find(hay, 11, "world" as *u8)
111 if off1 != 6 { return 61 }
112 let off2: nx_int = nx_chem_buf_find(hay, 11, "xyz" as *u8)
113 if off2 != -1 { return 62 }
114 return 0
115}
116
117// =================================================================
118// G -- Full JSON report emission for a 2-peak sample
119// Validates that the emitted JSON contains the expected key markers.
120// =================================================================
121func g_full_json_report() -> nx_int {
122 // Build a peak list with sibutramine + caffeine
123 let db: *AdulterantDB = nx_chem_adulterant_db_seed()
124 let e_sib: *AdulterantEntry = ((db.entries as nx_int) + (4 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry
125 let e_caf: *AdulterantEntry = ((db.entries as nx_int) + (5 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry
126 let pl: *PeakList = nx_chem_peak_list_new(8)
127 let _a1: nx_int = nx_chem_peak_list_add(pl, e_sib.mh_plus_q4, 100000, 742300)
128 let _a2: nx_int = nx_chem_peak_list_add(pl, e_caf.mh_plus_q4, 150000, 234100)
129 let buf: *u8 = sys_mmap(16384)
130 let n: nx_int = nx_chem_emit_report_json(buf, pl, db, "SUSPECT-2026-001" as *u8, 5)
131 // Validate JSON
132 if buf[0] as nx_int != 0x7B { return 71 } // must start with {
133 if buf[n - 1] as nx_int != 0x7D { return 72 } // must end with }
134 if nx_chem_buf_find(buf, n, "sibutramine" as *u8) < 0 { return 73 }
135 if nx_chem_buf_find(buf, n, "BANNED" as *u8) < 0 { return 74 }
136 if nx_chem_buf_find(buf, n, "REJECT" as *u8) < 0 { return 75 }
137 if nx_chem_buf_find(buf, n, "caffeine" as *u8) < 0 { return 76 }
138 if nx_chem_buf_find(buf, n, "APPROVED" as *u8) < 0 { return 77 }
139 if nx_chem_buf_find(buf, n, "FDA 2010" as *u8) < 0 { return 78 }
140 if nx_chem_buf_find(buf, n, "280.18" as *u8) < 0 { return 79 }
141 if nx_chem_buf_find(buf, n, "tolerance_ppm" as *u8) < 0 { return 80 }
142 if nx_chem_buf_find(buf, n, "SUSPECT-2026-001" as *u8) < 0 { return 81 }
143 return 0
144}
145
146// =================================================================
147// H -- verdict recommendation logic
148// =================================================================
149func h_verdict_logic() -> nx_int {
150 // banned > 0 -> REJECT
151 let r1: *u8 = nx_chem_verdict_recommendation(1, 0, 0)
152 if r1[0] as nx_int != 0x52 { return 91 } // 'R'
153 if r1[1] as nx_int != 0x45 { return 92 } // 'E' (REJECT)
154 if r1[2] as nx_int != 0x4A { return 93 } // 'J' (REJECT)
155 // banned=0 restricted>0 -> REVIEW
156 let r2: *u8 = nx_chem_verdict_recommendation(0, 1, 0)
157 if r2[0] as nx_int != 0x52 { return 94 }
158 if r2[2] as nx_int != 0x56 { return 95 } // 'V' (REVIEW)
159 // banned=0 restricted=0 unknown>0 -> RETEST
160 let r3: *u8 = nx_chem_verdict_recommendation(0, 0, 1)
161 if r3[2] as nx_int != 0x54 { return 96 } // 'T' (RETEST)
162 // all zero -> ACCEPT
163 let r4: *u8 = nx_chem_verdict_recommendation(0, 0, 0)
164 if r4[0] as nx_int != 0x41 { return 97 } // 'A' (ACCEPT)
165 return 0
166}
167
168// =================================================================
169// END-TO-END DEMO: build peak list, emit JSON, print to stdout.
170// =================================================================
171func run_json_demo() -> nx_int {
172 println("" as *u8)
173 println("==================================================================" as *u8)
174 println(" STRUCTURED JSON REPORT (LIMS-ready output)" as *u8)
175 println("==================================================================" as *u8)
176 let db: *AdulterantDB = nx_chem_adulterant_db_seed()
177 let pl: *PeakList = nx_chem_peak_list_new(8)
178 let e_sib: *AdulterantEntry = ((db.entries as nx_int) + (4 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry
179 let e_dmaa: *AdulterantEntry = ((db.entries as nx_int) + (1 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry
180 let e_caf: *AdulterantEntry = ((db.entries as nx_int) + (5 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry
181 let _a1: nx_int = nx_chem_peak_list_add(pl, e_sib.mh_plus_q4, 99523, 742300)
182 let _a2: nx_int = nx_chem_peak_list_add(pl, e_dmaa.mh_plus_q4, 87431, 45200)
183 let _a3: nx_int = nx_chem_peak_list_add(pl, e_caf.mh_plus_q4, 150000, 234100)
184 let _a4: nx_int = nx_chem_peak_list_add(pl, 9999999, 100, 12300)
185 let buf: *u8 = sys_mmap(16384)
186 let n: nx_int = nx_chem_emit_report_json(buf, pl, db, "SUSPECT-2026-001" as *u8, 5)
187 let _w: i64 = sys_write(1, buf, n as i64)
188 println("" as *u8)
189 println("==================================================================" as *u8)
190 let _l1: i64 = print(" JSON length: " as *u8)
191 let _l2: i64 = print_i64(n as i64)
192 let _l3: i64 = println(" bytes" as *u8)
193 println(" Format: single-line JSON suitable for LIMS pipe-through" as *u8)
194 println("==================================================================" as *u8)
195 return 0
196}
197
198func main() -> nx_exit {
199 println("=== nx_chem_report_json -- C6.0 KAT: LIMS-ready JSON output ===" as *u8)
200
201 let ra: nx_int = a_emit_str()
202 if ra != 0 { println("A emit_str FAIL" as *u8); return ra }
203 println("A emit_str PASS literal byte copy works" as *u8)
204
205 let rb: nx_int = b_emit_str_escaped_quote()
206 if rb != 0 { println("B emit_str_escaped FAIL" as *u8); return rb }
207 println("B emit_str_escaped PASS wraps in quotes + escapes internal \"" as *u8)
208
209 let rc: nx_int = c_emit_int()
210 if rc != 0 { println("C emit_int FAIL" as *u8); return rc }
211 println("C emit_int PASS handles 0, positive, negative" as *u8)
212
213 let rd: nx_int = d_emit_q4()
214 if rd != 0 { println("D emit_q4 FAIL" as *u8); return rd }
215 println("D emit_q4 PASS '280.1826' rendered correctly" as *u8)
216
217 let re: nx_int = e_emit_q4_padded()
218 if re != 0 { println("E emit_q4_padded FAIL" as *u8); return re }
219 println("E emit_q4_padded PASS short fractional zero-padded" as *u8)
220
221 let rf: nx_int = f_buf_find()
222 if rf != 0 { println("F buf_find FAIL" as *u8); return rf }
223 println("F buf_find PASS substring search finds + handles absent" as *u8)
224
225 let rg: nx_int = g_full_json_report()
226 if rg != 0 { println("G full_json_report FAIL" as *u8); return rg }
227 println("G full_json_report PASS emitted JSON has all expected key markers" as *u8)
228
229 let rh: nx_int = h_verdict_logic()
230 if rh != 0 { println("H verdict_logic FAIL" as *u8); return rh }
231 println("H verdict_logic PASS REJECT > REVIEW > RETEST > ACCEPT priority" as *u8)
232
233 let _demo: nx_int = run_json_demo()
234
235 println("" as *u8)
236 println("=== C6.0 substrate milestone PASS ===" as *u8)
237 println(" Bits-up JSON emitter: emit_str, emit_str_escaped, emit_int," as *u8)
238 println(" emit_q4 (Q4 -> 'DDD.MMMM' zero-padded), emit_char" as *u8)
239 println(" emit_report_json: full report from PeakList + AdulterantDB" as *u8)
240 println(" Verdict recommendation: REJECT (banned) > REVIEW (restricted) >" as *u8)
241 println(" RETEST (unknown) > ACCEPT (all clear)" as *u8)
242 println(" LIMS integration ready: machine-parseable single-line JSON" as *u8)
243 println("" as *u8)
244 println(" Honest gaps: numeric escape for non-ASCII (not needed yet -- our" as *u8)
245 println(" citations are pure ASCII), CBOR/MessagePack binary" as *u8)
246 println(" serialization (C6.1), retention-time as 2nd dim (C7.0)" as *u8)
247 return 0
248}