@@ -0,0 +1,142 @@
1+:: Narrow closed program-main checking, without execution or watchability claims.
2+/+ jibb
3+/* prelude %jibb /lib/jibb/prelude/jibb
4+/* internal %jibb /lib/jibb/internal/jibb
5+/* source %txt /tests/type-program-main/source/txt
6+/* consumer %txt /tests/type-program-main/consumer/txt
7+/* gate-model %txt /tests/type-program-main/gate-model/txt
8+/* gate-data %txt /tests/type-program-main/gate-data/txt
9+/* nonempty-subs %txt /tests/type-program-main/nonempty-subs/txt
10+/* mismatched-model %txt /tests/type-program-main/mismatched-model/txt
11+/* arbitrary-main %txt /tests/type-program-main/arbitrary-main/txt
12+/* alias-main %txt /tests/type-program-main/alias-main/txt
13+/* open-message %txt /tests/type-program-main/open-message/txt
14+|%
15+++ text
16+ |= lines=wain
17+ ^- @t
18+ (rap 3 (turn lines |=(line=@t (cat 3 line '\0a'))))
19+::
20+++ program-prepared
21+ |= [public=@t private=@t]
22+ ^- (unit iprelude:jibb)
23+ =/ extra=@t '\0a+$ element |$ [M] [%node item=M]\0a+$ program |$ [D X M]\0a [init=$-(D X) update=$-([M X] [X (list (cmd M))]) view=$-(X (element M)) subs=$-(X (list (sub M)))]\0a++ program |= [init=$-(D X) update=$-([M X] [X (list (cmd M))]) view=$-(X (element M)) subs=$-(X (list (sub M)))]\0a ^- (program D X M) [init update view subs]\0a'
24+ (prepare-prelude-with-internal:jibb (cat 3 public extra) private)
25+::
26+++ program-main-detailed
27+ |= [at=path src=@t modules=jbundle:jibb prepared=iprelude:jibb]
28+ ^- jfile-detailed-result:jibb
29+ (infer-jibb-file-detailed:jibb at src ~ ~ modules ~[at] values.prepared molds.prepared ~ `iface.prepared)
30+::
31+++ program-main-legacy
32+ |= [at=path src=@t modules=jbundle:jibb prepared=iprelude:jibb]
33+ ^- jfile-result:jibb
34+ (infer-jibb-file:jibb at src ~ ~ modules ~[at] values.prepared molds.prepared ~ `iface.prepared)
35+::
36+++ program-main-negative-errors
37+ |= [label=@t at=path src=@t prepared=iprelude:jibb]
38+ ^- (list tape)
39+ =/ detailed=jfile-detailed-result:jibb (program-main-detailed at src ~ prepared)
40+ ?: ?=(%& -.detailed) ~[(weld (trip label) ": structured check accepted")]
41+ ?. ?=(~ overlap.p.detailed) ~[(weld (trip label) ": unexpected overlap evidence")]
42+ =/ legacy=jfile-result:jibb (program-main-legacy at src ~ prepared)
43+ ?: ?=(%& -.legacy) ~[(weld (trip label) ": legacy check accepted")]
44+ ?. =(p.legacy message.p.detailed) ~[(weld (trip label) ": adapter messages differ")]
45+ ~
46+::
47+++ program-main-errors
48+ |= [public=@t private=@t island=@t downstream=@t negatives=(list @t)]
49+ ^- (list tape)
50+ =/ prepared=(unit iprelude:jibb)
51+ (program-prepared public private)
52+ ?~ prepared ~["synthetic program prelude did not prepare"]
53+ =/ at=path /tests/program-main/island/jibb
54+ =/ detailed=jfile-detailed-result:jibb (program-main-detailed at island ~ u.prepared)
55+ ?: ?=(%| -.detailed) ~["direct closed program main was rejected"]
56+ =/ checked=ifile:jibb iface.p.detailed
57+ =/ legacy=jfile-result:jibb (program-main-legacy at island ~ u.prepared)
58+ ?: ?=(%| -.legacy) ~["legacy adapter rejected a closed program main"]
59+ ?. =(values.checked values.iface.p.legacy) ~["structured and legacy interface values differ"]
60+ =/ init=(unit ischeme:jibb) (ienv-lookup:jibb %init values.checked)
61+ =/ update=(unit ischeme:jibb) (ienv-lookup:jibb %update values.checked)
62+ =/ view=(unit ischeme:jibb) (ienv-lookup:jibb %view values.checked)
63+ =/ subs=(unit ischeme:jibb) (ienv-lookup:jibb %subs values.checked)
64+ =/ main=(unit ischeme:jibb) (ienv-lookup:jibb %main values.checked)
65+ ?~ init ~["init interface is missing"]
66+ ?~ update ~["update interface is missing"]
67+ ?~ view ~["view interface is missing"]
68+ ?~ subs ~["subs interface is missing"]
69+ ?~ main ~["main interface is missing"]
70+ =/ parsed (parse:jibb at island)
71+ ?: ?=(%| -.parsed) ~["program source no longer parses"]
72+ =/ main-def=(unit def:jibb) (program-main-def:jibb defs.p.parsed)
73+ ?~ main-def ~["program main definition is missing"]
74+ =/ parts (program-main-parts:jibb u.main-def)
75+ ?~ parts ~["program main parts are missing"]
76+ ?: (program-main-closed:jibb u.parts defs.p.parsed values.checked ~)
77+ ~["program kind was accepted without its source-backed prelude"]
78+ =/ program-scheme=(unit ischeme:jibb) (ienv-lookup:jibb %program values.iface.u.prepared)
79+ ?~ program-scheme ~["synthetic program scheme is missing"]
80+ ?. ?=(%fn -.typ.u.program-scheme) ~["synthetic program value is not a gate"]
81+ =/ broken-values=ienv:jibb
82+ (skim values.iface.u.prepared |=(entry=[name=term scheme=ischeme:jibb] !=(%program name.entry)))
83+ =/ broken=ifile:jibb
84+ iface.u.prepared(values [[%program [[%fn sample.typ.u.program-scheme [%atom %ud]] vars.u.program-scheme]] broken-values])
85+ =/ malformed=jfile-detailed-result:jibb
86+ (infer-jibb-file-detailed:jibb at island ~ ~ ~ ~[at] values.u.prepared molds.u.prepared ~ `broken)
87+ ?: ?=(%& -.malformed) ~["program result was not checked against the program mold"]
88+ =/ kind-error=@t (crip "module kind needs unsupported inference: {(spud at)}")
89+ ?. =(message.p.malformed kind-error) ~["malformed program failed before the kind check"]
90+ =/ open=jfile-detailed-result:jibb
91+ (program-main-detailed at (snag 6 negatives) ~ u.prepared)
92+ ?: ?=(%& -.open) ~["open program message was accepted"]
93+ =/ other-values=ienv:jibb
94+ (skim values.checked |=(entry=[name=term scheme=ischeme:jibb] !=(%main name.entry)))
95+ =/ open-values=ienv:jibb [[%main u.main(vars ~[0])] other-values]
96+ ?: (program-main-closed:jibb u.parts defs.p.parsed open-values `iface.u.prepared)
97+ ~["generic main scheme passed the closure check"]
98+ =/ model=itype:jibb [%face %count [%atom %ud]]
99+ ?. =(u.init [[%fn [%atom %t] model] ~]) ~["init interface type differs"]
100+ ?. ?=(~ vars.u.main) ~["main interface is not closed"]
101+ =/ init-fields=(list itype:jibb) (record-fields-named:jibb %init typ.u.main ~)
102+ =/ update-fields=(list itype:jibb) (record-fields-named:jibb %update typ.u.main ~)
103+ =/ view-fields=(list itype:jibb) (record-fields-named:jibb %view typ.u.main ~)
104+ =/ subs-fields=(list itype:jibb) (record-fields-named:jibb %subs typ.u.main ~)
105+ ?. =(init-fields ~[typ.u.init]) ~["main initializer field differs"]
106+ ?. &(=(1 (lent update-fields)) =(1 (lent view-fields)) =(1 (lent subs-fields)))
107+ ~["main component fields differ"]
108+ ?~ source.checked ~["program source evidence is missing"]
109+ ?. =(u.source.checked island) ~["program source evidence differs"]
110+ ?~ graph.checked ~["program request graph evidence is missing"]
111+ =/ consumer-at=path /tests/program-main/consumer/jibb
112+ =/ imported=jfile-detailed-result:jibb
113+ (program-main-detailed consumer-at downstream ~[[at island]] u.prepared)
114+ ?: ?=(%| -.imported) ~["ordinary downstream program import was rejected"]
115+ =/ use=(unit ischeme:jibb) (ienv-lookup:jibb %imported values.iface.p.imported)
116+ ?~ use ~["downstream imported initializer is missing"]
117+ ?. =(u.use u.init) ~["downstream imported initializer type differs"]
118+ ?. =(7 (lent negatives)) ~["focused negative fixture count differs"]
119+ =/ cases=(list [label=@t at=path src=@t])
120+ :~ ['gate in model' at (snag 0 negatives)]
121+ ['gate in data' at (snag 1 negatives)]
122+ ['nonempty subs' at (snag 2 negatives)]
123+ ['mismatched model' at (snag 3 negatives)]
124+ ['arbitrary main' at (snag 4 negatives)]
125+ ['store path' /ui/stores/program-main/jibb island]
126+ ['program alias' at (snag 5 negatives)]
127+ ==
128+ (zing (turn cases |=(c=[label=@t at=path src=@t] (program-main-negative-errors label.c at.c src.c u.prepared))))
129+::
130+++ test-program-main
131+ ^- tang
132+ =/ negatives=(list @t)
133+ :~ (text gate-model)
134+ (text gate-data)
135+ (text nonempty-subs)
136+ (text mismatched-model)
137+ (text arbitrary-main)
138+ (text alias-main)
139+ (text open-message)
140+ ==
141+ (turn (program-main-errors prelude internal (text source) (text consumer) negatives) |=(reason=tape leaf+reason))
142+--