Files
Viper_RegressionTesting/HashTableTest/App/main.vp
T
TermiNexus 3c6fb1d246 chore(test): 初始化回归测试仓(新增 .gitignore,TestsOverview.md 改为 README.md)
把 Test/ 纳入 https://git.gvsds.com/GVSDS/Viper_RegressionTesting 。

1) 新增 .gitignore —— 只保留测试源码,剔除全部构建产物:
   目录   **/output*/(output / output_opt / output_orig / output_verify / output_dbg)、
          **/temp*/(temp / temp_opt)、**/.tpv_build/
   二进制 *.exe *.obj *.o *.out *.a *.lib *.dll
   中间物 *.ll *.vpi *.pyi *.deps.txt *.deps.json *.doc.json *_sha1_map.txt
          _pyi_cache_v1.pkl _pyi_cache_v1.sig.json _shared_sym.json _phase1_manifest.json
   其它   build_all.txt(构建日志)、*.log、__pycache__/、*.bak、IDE 目录
   保留   App/*.vp、project.json / project_opt.json / project.vpj、README.md、两个 .py
   实测 `git add -A --dry-run`:196 个文件,无任何构建产物混入。

2) TestsOverview.md → README.md(作为仓库首页文档)。

3) SequentialRegressionTest.py:7 处 TestsOverview.md 引用同步改为 README.md
   (文档串、OVERVIEW 路径、read_test_order 文档与报错文案、argparse description、
   启动横幅);同时修正入口路径 PROJECTRANS —— 旧值 <root>/Projectrans.py 已不存在,
   改为 <root>/TransPyC/Projectrans.py(与 regression_test.py:45-48 记录一致),
   否则本脚本会以 "can't open file" 全量失败。
   regression_test.py 无需改动:它按目录扫描 project.json 找项目,不引用该文档。
2026-09-29 15:14:59 +08:00

211 lines
8.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from stdint import *
import w32.win32console
import t, c
from t import CInt, CExport
import stdio
import stdlib
import string
import memhub
import hashtable
import testcheck
def main() -> CInt | CExport:
w32.win32console.SetConsoleCP(65001)
w32.win32console.SetConsoleOutputCP(65001)
testcheck.begin("HashTableTest: 开放寻址哈希表测试")
# 分配内存竞技场
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
# === Test 1: 基本插入和查找 ===
testcheck.section("Test 1: 基本插入和查找 (set_int)")
ht: hashtable.HashTable = hashtable.HashTable(bd)
ht.set_int("alpha", 10)
ht.set_int("beta", 20)
ht.set_int("gamma", 30)
n: t.CSizeT = len(ht)
stdio.printf("len=%lu\n", n)
testcheck.check(n == 3, "ht len OK (3)", "ht len FAILED")
# 哈希表的 int 值按 int(i32)写入(见 hashtable.vp set_int 的 int_ptr),读回
# 须给出有元素类型的指针:c.Deref 的宽度只认 pointee 类型,i8*(t.CPtr)恒读
# 1 字节,不再按赋值目标注解反推 4 字节。
p1: t.CPtr = ht["alpha"]
v1: int = c.Deref((int | t.CPtr)(p1))
p2: t.CPtr = ht["beta"]
v2: int = c.Deref((int | t.CPtr)(p2))
p3: t.CPtr = ht["gamma"]
v3: int = c.Deref((int | t.CPtr)(p3))
stdio.printf("alpha=%d beta=%d gamma=%d\n", v1, v2, v3)
testcheck.check(v1 == 10, "ht[alpha]==10 OK", "ht[alpha] FAILED")
testcheck.check(v2 == 20, "ht[beta]==20 OK", "ht[beta] FAILED")
testcheck.check(v3 == 30, "ht[gamma]==30 OK", "ht[gamma] FAILED")
# === Test 2: 更新已有键 ===
testcheck.section("Test 2: 更新已有键")
ht.set_int("beta", 99)
p2b: t.CPtr = ht["beta"]
v2b: int = c.Deref((int | t.CPtr)(p2b))
stdio.printf("beta(updated)=%d\n", v2b)
testcheck.check(v2b == 99, "ht update OK", "ht update FAILED")
testcheck.check(len(ht) == 3, "ht len still 3 OK", "ht len changed FAILED")
# === Test 3: get with default ===
testcheck.section("Test 3: get with default")
gv: t.CPtr = ht.get("missing", None)
testcheck.check(gv == None, "ht get missing OK (None)", "ht get missing FAILED")
gp: t.CPtr = ht.get("alpha", None)
ga: int = c.Deref((int | t.CPtr)(gp))
stdio.printf("get(alpha)=%d\n", ga)
testcheck.check(ga == 10, "ht get existing OK", "ht get existing FAILED")
# === Test 4: contains ===
testcheck.section("Test 4: contains (in)")
has_alpha: t.CInt = "alpha" in ht
has_missing: t.CInt = "missing" in ht
stdio.printf("contains(alpha)=%d contains(missing)=%d\n", has_alpha, has_missing)
testcheck.check(has_alpha == 1, "contains alpha OK", "contains alpha FAILED")
testcheck.check(has_missing == 0, "not contains missing OK", "contains missing FAILED")
# === Test 5: 删除 ===
testcheck.section("Test 5: 删除 (del)")
deleted: t.CInt = ht.__delitem__("beta")
stdio.printf("del beta=%d\n", deleted)
testcheck.check(deleted == 1, "del beta OK", "del beta FAILED")
testcheck.check(len(ht) == 2, "ht len 2 after del OK", "ht len after del FAILED")
has_beta: t.CInt = "beta" in ht
testcheck.check(has_beta == 0, "beta gone OK", "beta still exists FAILED")
# 删除不存在的 key
del_missing: t.CInt = ht.__delitem__("nokey")
testcheck.check(del_missing == 0, "del missing returns 0 OK", "del missing FAILED")
# === Test 6: 删除后重新插入 ===
testcheck.section("Test 6: 删除后重新插入")
ht.set_int("beta", 555)
p2c: t.CPtr = ht["beta"]
v2c: int = c.Deref((int | t.CPtr)(p2c))
stdio.printf("beta(re-inserted)=%d\n", v2c)
testcheck.check(v2c == 555, "ht re-insert beta OK", "ht re-insert beta FAILED")
testcheck.check(len(ht) == 3, "ht len 3 after re-insert OK", "ht len after re-insert FAILED")
# === Test 7: 迭代器 ===
testcheck.section("Test 7: 迭代器 for key in ht")
iter_count: int = 0
for key in ht:
kp: t.CPtr = ht[key]
val: int = c.Deref((int | t.CPtr)(kp))
stdio.printf("ht[%s]=%d\n", key, val)
iter_count += 1
testcheck.check(iter_count == 3, "ht iter OK (3)", "ht iter FAILED")
# === Test 8: 字符串值 ===
testcheck.section("Test 8: 字符串值 (set_str)")
ht2: hashtable.HashTable = hashtable.HashTable(bd)
ht2.set_str("name", "Alice")
ht2.set_str("city", "Beijing")
ht2.set_str("lang", "TransPyC")
n2: t.CSizeT = len(ht2)
stdio.printf("ht2 len=%lu\n", n2)
testcheck.check(n2 == 3, "ht set_str len OK (3)", "ht set_str len FAILED")
name_p: t.CPtr = ht2["name"]
city_p: t.CPtr = ht2["city"]
lang_p: t.CPtr = ht2["lang"]
name: str = name_p
city: str = city_p
lang: str = lang_p
stdio.printf("name=%s city=%s lang=%s\n", name, city, lang)
# i8* == 是指针地址比较(C-Like 语义),内容比较需显式 strcmp
testcheck.check(string.strcmp(name, "Alice") == 0, "ht str name OK", "ht str name FAILED")
testcheck.check(string.strcmp(city, "Beijing") == 0, "ht str city OK", "ht str city FAILED")
testcheck.check(string.strcmp(lang, "TransPyC") == 0, "ht str lang OK", "ht str lang FAILED")
# === Test 9: 扩容测试 ===
testcheck.section("Test 9: 扩容测试 (>16 个元素)")
ht3: hashtable.HashTable = hashtable.HashTable(bd)
i: int = 0
while i < 50:
key_buf: str = stdlib.malloc(16)
stdio.sprintf(key_buf, "key%d", i)
ht3.set_int(key_buf, i * 100)
i += 1
n3: t.CSizeT = len(ht3)
stdio.printf("ht3 len=%lu (after 50 inserts)\n", n3)
testcheck.check(n3 == 50, "ht expand OK (50)", "ht expand FAILED")
# 验证几个值
k5: str = stdlib.malloc(16)
stdio.sprintf(k5, "key5")
p5: t.CPtr = ht3[k5]
v5: int = c.Deref((int | t.CPtr)(p5))
stdio.printf("ht3[key5]=%d\n", v5)
testcheck.check(v5 == 500, "ht expand key5 OK", "ht expand key5 FAILED")
k25: str = stdlib.malloc(16)
stdio.sprintf(k25, "key25")
p25: t.CPtr = ht3[k25]
v25: int = c.Deref((int | t.CPtr)(p25))
stdio.printf("ht3[key25]=%d\n", v25)
testcheck.check(v25 == 2500, "ht expand key25 OK", "ht expand key25 FAILED")
k49: str = stdlib.malloc(16)
stdio.sprintf(k49, "key49")
p49: t.CPtr = ht3[k49]
v49: int = c.Deref((int | t.CPtr)(p49))
stdio.printf("ht3[key49]=%d\n", v49)
testcheck.check(v49 == 4900, "ht expand key49 OK", "ht expand key49 FAILED")
# === Test 10: 扩容后迭代 ===
testcheck.section("Test 10: 扩容后迭代")
iter_count3: int = 0
for k in ht3:
iter_count3 += 1
stdio.printf("ht3 iter count=%d\n", iter_count3)
testcheck.check(iter_count3 == 50, "ht expand iter OK (50)", "ht expand iter FAILED")
# === Test 11: 删除后扩容 ===
testcheck.section("Test 11: 批量删除后操作")
j: int = 0
while j < 25:
del_buf: str = stdlib.malloc(16)
stdio.sprintf(del_buf, "key%d", j)
del ht3[del_buf]
j += 1
n3b: t.CSizeT = len(ht3)
stdio.printf("ht3 len=%lu (after 25 deletes)\n", n3b)
testcheck.check(n3b == 25, "ht after del OK (25)", "ht after del FAILED")
# 验证剩余的值
k30: str = stdlib.malloc(16)
stdio.sprintf(k30, "key30")
p30: t.CPtr = ht3[k30]
v30: int = c.Deref((int | t.CPtr)(p30))
stdio.printf("ht3[key30]=%d\n", v30)
testcheck.check(v30 == 3000, "ht key30 after del OK", "ht key30 after del FAILED")
# 验证已删除的 key 不存在
k0: str = stdlib.malloc(16)
stdio.sprintf(k0, "key0")
has_k0: t.CInt = k0 in ht3
testcheck.check(has_k0 == 0, "ht key0 deleted OK", "ht key0 still exists FAILED")
# === Test 12: 空表操作 ===
testcheck.section("Test 12: 空表操作")
ht4: hashtable.HashTable = hashtable.HashTable(bd)
testcheck.check(len(ht4) == 0, "empty ht len 0 OK", "empty ht len FAILED")
empty_get: t.CPtr = ht4.get("none", None)
testcheck.check(empty_get == None, "empty ht get OK", "empty ht get FAILED")
has_none: t.CInt = "none" in ht4
testcheck.check(has_none == 0, "empty ht contains OK", "empty ht contains FAILED")
empty_iter: int = 0
for ek in ht4:
empty_iter += 1
testcheck.check(empty_iter == 0, "empty ht iter OK (0)", "empty ht iter FAILED")
stdlib.free(arena)
return testcheck.end()