1+ const HC = require ( "./js/hic.js" ) ;
2+
3+ let pass = 0 , fail = 0 ;
4+ function ok ( cond , label ) { if ( cond ) { pass ++ ; } else { fail ++ ; console . log ( " ✗ " + label ) ; } }
5+
6+ // ---- 1. 变量声明解析 ----
7+ let r = HC . classify ( "it title t 你好 HiCode" ) ;
8+ ok ( r . kind === "it" && r . name === "title" && r . vtype === "text" && r . value === "你好 HiCode" , "it title t" ) ;
9+
10+ r = HC . classify ( "it logo p" ) ;
11+ ok ( r . kind === "it" && r . name === "logo" && r . vtype === "img" && r . value === "" , "it logo p" ) ;
12+
13+ r = HC . classify ( "it age int 18" ) ;
14+ ok ( r . kind === "it" && r . name === "age" && r . vtype === "ordinary" , "it age int -> ordinary" ) ;
15+
16+ r = HC . classify ( "it msg" ) ;
17+ ok ( r . kind === "it" && r . name === "msg" && r . vtype === "ordinary" , "it msg -> ordinary" ) ;
18+
19+ // ---- 2. in 展示 ----
20+ r = HC . classify ( "title in t" ) ;
21+ ok ( r . kind === "in" && r . mode === "text" , "in t" ) ;
22+ r = HC . classify ( "logo in p" ) ;
23+ ok ( r . kind === "in" && r . mode === "img" , "in p" ) ;
24+
25+ // ---- 3. 条件头 ----
26+ ok ( HC . classify ( "if age == 18:" ) . type === "if" , "if头" ) ;
27+ ok ( HC . classify ( "orif age > 18:" ) . type === "orif" , "orif头" ) ;
28+ ok ( HC . classify ( "noif:" ) . type === "noif" , "noif头" ) ;
29+
30+ // ---- 4. 表达式求值 ----
31+ ok ( HC . evalExpr ( "age == 18" , { age : { value : 18 } } ) === true , "数值比较" ) ;
32+ ok ( HC . evalExpr ( "1 == 1 and 2 > 1" , { } ) === true , "and" ) ;
33+ ok ( HC . evalExpr ( "1 > 2 or 3 == 3" , { } ) === true , "or" ) ;
34+ ok ( HC . evalExpr ( "not (1 == 2)" , { } ) === true , "not" ) ;
35+ ok ( HC . evalExpr ( "'hello' in 'xxhello'" , { } ) === true , "in子串" ) ;
36+
37+ // ---- 5. 导向解析 ----
38+ r = HC . parseNav ( "home to about" ) ;
39+ ok ( r && ! r . cross && r . fromPage === "home" && r . toPage === "about" , "同项目 x to y" ) ;
40+ r = HC . parseNav ( "to about" ) ;
41+ ok ( r && ! r . cross && r . fromPage === null && r . toPage === "about" , "to y(当前页)" ) ;
42+ r = HC . parseNav ( "fr 我的项目 首页 big to 我的项目 关于" ) ;
43+ ok ( r && r . cross && r . toProj === "我的项目" , "跨项目 fr 项目 页面 big to" ) ;
44+
45+ // ---- 6. 端到端:解析+语义 -> 元素 ----
46+ const page = {
47+ name : "index" ,
48+ code : [
49+ "it title t 你好,HiCode" ,
50+ "it intro t 简单上手的编程语言" ,
51+ "it logo p" ,
52+ "it count int 3" ,
53+ "if count == 3:" ,
54+ " intro in t" ,
55+ "noif:" ,
56+ " title in t" ,
57+ "to about"
58+ ] . join ( "\n" ) ,
59+ images : { logo : "data:image/png;base64,AAAA" }
60+ } ;
61+ const { vars, items } = HC . processPage ( page , { } ) ;
62+ ok ( Object . keys ( vars ) . length === 4 , "收集到4个变量" ) ;
63+ ok ( vars . logo . isImg === true && vars . logo . value === "data:image/png;base64,AAAA" , "p变量绑定图片" ) ;
64+ const texts = items . filter ( x => x . kind === "display" && x . mode === "text" ) ;
65+ ok ( texts . length === 1 && texts [ 0 ] . value === "简单上手的编程语言" , "if分支命中 intro(非 title)" ) ;
66+ const navs = items . filter ( x => x . kind === "nav" ) ;
67+ ok ( navs . length === 1 && navs [ 0 ] . toPage === "about" , "存在一个 to 导向" ) ;
68+
69+ // ---- 7. HTML 生成 ----
70+ const proj = { id : "p1" , name : "我的项目" , pages : { p_a : page , p_b : { id : "p_b" , name : "about" , code : "it hello t 关于我们\nhello in t" , images : { } } } } ;
71+ const merged = HC . buildProjectMergedHtml ( proj , { } ) ;
72+ ok ( merged . indexOf ( "data-page=\"我的项目::index\"" ) >= 0 , "合并含 index 区块" ) ;
73+ ok ( merged . indexOf ( "我的项目::about" ) >= 0 , "合并含 about 区块" ) ;
74+ ok ( merged . indexOf ( "简单上手的编程语言" ) >= 0 , "合并含文本内容" ) ;
75+ ok ( / < ! D O C T Y P E h t m l > / i. test ( merged ) , "含 HTML 骨架" ) ;
76+
77+ const single = HC . buildSinglePageHtml ( { name : "我的项目" } , page ) ;
78+ ok ( single . indexOf ( "你好,HiCode" ) >= 0 || single . indexOf ( "简单上手" ) >= 0 , "单页html含内容" ) ;
79+
80+ // ---- 8. ZIP ----
81+ const entries = HC . buildZipEntries ( [ proj ] ) ;
82+ ok ( entries . length === 2 , "zip有2个页面文件" ) ;
83+ const z = HC . zipFiles ( entries . map ( e => ( { name : e . name , data : e . html } ) ) ) ;
84+ ok ( z instanceof Uint8Array && z . length > 30 , "zip字节生成" ) ;
85+ // 校验 PK 头
86+ ok ( z [ 0 ] === 0x50 && z [ 1 ] === 0x4b , "zip魔数PK" ) ;
87+
88+ console . log ( "\n通过 " + pass + " 项,失败 " + fail + " 项" ) ;
89+ process . exit ( fail ? 1 : 0 ) ;
0 commit comments