nx_directors_note_test.nx source
↩ module page · 123 lines · 5878 B
1// nx_directors_note_test.nx -- smoke for canonical director envelope.
2
3import "nx_syscalls.nx"
4import "nx_tier.nx"
5import "nx_directors_note.nx"
6
7func main() -> nx_int {
8 // === Test 1: alloc + neutral defaults ============================
9 let dn: *DirectorsNote = nx_dn_alloc()
10 if dn.director_role != NX_DR_EXTERNAL_SYSTEM { return 1 }
11 if dn.content_domain != NX_CD_MUNDANE { return 2 }
12 if dn.affect_axis != NX_AF_NEUTRAL { return 3 }
13 if dn.perspective != NX_PERSP_VOYEUR { return 4 }
14 if dn.shot_size != NX_SHOT_MS { return 5 }
15 if dn.award_class != NX_DN_AWARD_UNVERIFIED { return 6 }
16 if dn.preflight_tier != NX_PFT_GOOD { return 7 }
17 if dn.refine_iteration != 0 { return 8 }
18 if dn.underspec_code != NX_DN_UNDERSPEC_NONE { return 9 }
19
20 // === Test 2: validate_for_render catches missing fields ========
21 // Fresh envelope has all required IDs = 0 -> should fail validation.
22 let code1: nx_int = nx_dn_validate_for_render(dn)
23 if code1 != NX_DN_UNDERSPEC_OUTFIT { return 10 } // first missing field
24
25 // Fill outfit -> next missing is LOCATION
26 dn.outfit_key_id = 7
27 let code2: nx_int = nx_dn_validate_for_render(dn)
28 if code2 != NX_DN_UNDERSPEC_LOCATION { return 11 }
29
30 // Fill location, pose, activity, character, body_archetype
31 dn.location_id = 1
32 dn.pose_id = 2
33 dn.activity_id = 3
34 dn.character_id = 4
35 dn.body_archetype_id = 5
36 let code3: nx_int = nx_dn_validate_for_render(dn)
37 if code3 != NX_DN_UNDERSPEC_NONE { return 12 } // now fully specified
38
39 // === Test 3: tier_from_award per graduated-intervention ======
40 if nx_dn_tier_from_award(NX_DN_AWARD_S_CLASS) != NX_PFT_GOOD { return 20 }
41 if nx_dn_tier_from_award(NX_DN_AWARD_A_CLASS) != NX_PFT_GOOD { return 21 }
42 if nx_dn_tier_from_award(NX_DN_AWARD_B_CLASS) != NX_PFT_DRIFT { return 22 }
43 if nx_dn_tier_from_award(NX_DN_AWARD_OFF_CANON) != NX_PFT_BROKEN { return 23 }
44 if nx_dn_tier_from_award(NX_DN_AWARD_UNVERIFIED) != NX_PFT_DRIFT { return 24 }
45
46 // === Test 4: companion-authored builder (Elara as director) ====
47 let dn2: *DirectorsNote = nx_dn_alloc()
48 nx_dn_companion_authored(dn2, 42, NX_CD_EROTIC, NX_AF_PLAYFUL)
49 if dn2.director_role != NX_DR_COMPANION { return 30 }
50 if dn2.source_tag != NX_ST_COMPANION_DECISION { return 31 }
51 if dn2.character_id != 42 { return 32 }
52 if dn2.content_domain != NX_CD_EROTIC { return 33 }
53 if dn2.affect_axis != NX_AF_PLAYFUL { return 34 }
54
55 // === Test 5: external-system builder (batch driver) ============
56 let dn3: *DirectorsNote = nx_dn_alloc()
57 nx_dn_external_system_authored(dn3, 100, 4, 17, NX_CD_FANTASY)
58 if dn3.director_role != NX_DR_EXTERNAL_SYSTEM { return 40 }
59 if dn3.source_tag != NX_ST_STAGE_POOL { return 41 }
60 if dn3.arc_id != 100 { return 42 }
61 if dn3.arc_stage != 4 { return 43 }
62 if dn3.moment_seq != 17 { return 44 }
63 if dn3.content_domain != NX_CD_FANTASY { return 45 }
64
65 // === Test 6: sealed-enum validators ============================
66 if nx_dr_role_is_valid(NX_DR_EXTERNAL_USER) != 1 { return 50 }
67 if nx_dr_role_is_valid(NX_DR_COMPANION) != 1 { return 51 }
68 if nx_dr_role_is_valid(NX_DR_N_ROLES) != 0 { return 52 }
69 if nx_dr_role_is_valid(99) != 0 { return 53 }
70 if nx_dr_role_is_valid(0 - 1) != 0 { return 54 }
71
72 if nx_cd_domain_is_valid(NX_CD_MUNDANE) != 1 { return 55 }
73 if nx_cd_domain_is_valid(NX_CD_RPG) != 1 { return 56 }
74 if nx_cd_domain_is_valid(NX_CD_N_DOMAINS) != 0 { return 57 }
75
76 if nx_af_axis_is_valid(NX_AF_FOCUSED) != 1 { return 60 }
77 if nx_af_axis_is_valid(NX_AF_REVERENT) != 1 { return 61 }
78 if nx_af_axis_is_valid(NX_AF_N_AXES) != 0 { return 62 }
79
80 if nx_st_tag_is_valid(NX_ST_CONSTELLATION) != 1 { return 70 }
81 if nx_st_tag_is_valid(NX_ST_POV_SCENARIO) != 1 { return 71 }
82 if nx_st_tag_is_valid(NX_ST_N_TAGS) != 0 { return 72 }
83
84 if nx_dn_award_is_valid(NX_DN_AWARD_S_CLASS) != 1 { return 80 }
85 if nx_dn_award_is_valid(NX_DN_AWARD_OFF_CANON) != 1 { return 81 }
86 if nx_dn_award_is_valid(99) != 0 { return 82 }
87
88 if nx_pft_tier_is_valid(NX_PFT_GOOD) != 1 { return 90 }
89 if nx_pft_tier_is_valid(NX_PFT_BROKEN) != 1 { return 91 }
90 if nx_pft_tier_is_valid(99) != 0 { return 92 }
91
92 if nx_persp_is_valid(NX_PERSP_POV) != 1 { return 100 }
93 if nx_persp_is_valid(NX_PERSP_SELFIE) != 1 { return 101 }
94 if nx_persp_is_valid(99) != 0 { return 102 }
95
96 if nx_shot_is_valid(NX_SHOT_ECU) != 1 { return 110 }
97 if nx_shot_is_valid(NX_SHOT_FS) != 1 { return 111 }
98 if nx_shot_is_valid(99) != 0 { return 112 }
99
100 if nx_bmk_kind_is_valid(NX_BMK_HICKEY) != 1 { return 120 }
101 if nx_bmk_kind_is_valid(NX_BMK_FLUSH) != 1 { return 121 }
102 if nx_bmk_kind_is_valid(99) != 0 { return 122 }
103
104 if nx_dn_underspec_is_valid(NX_DN_UNDERSPEC_OUTFIT) != 1 { return 130 }
105 if nx_dn_underspec_is_valid(NX_DN_UNDERSPEC_BODY_ARCHETYPE) != 1 { return 131 }
106 if nx_dn_underspec_is_valid(99) != 0 { return 132 }
107
108 // === Test 7: domain agnosticism — same envelope, different domains ===
109 // The director can route the same struct to MUNDANE / EROTIC / FANTASY
110 // / RPG / INTIMATE / NARRATIVE without any structural change. This is
111 // the content-domain-agnostic property the cardinal demands.
112 let dn4: *DirectorsNote = nx_dn_alloc()
113 dn4.content_domain = NX_CD_MUNDANE
114 if nx_dn_content_domain(dn4) != NX_CD_MUNDANE { return 140 }
115 dn4.content_domain = NX_CD_FANTASY
116 if nx_dn_content_domain(dn4) != NX_CD_FANTASY { return 141 }
117 dn4.content_domain = NX_CD_INTIMATE
118 if nx_dn_content_domain(dn4) != NX_CD_INTIMATE { return 142 }
119 dn4.content_domain = NX_CD_RPG
120 if nx_dn_content_domain(dn4) != NX_CD_RPG { return 143 }
121
122 return 0
123}