机械规则 R2/R3/R4/R6/R7/R8/R13 + R16 保守子集,共 86 文件 2127 行。R1(T | t.CPtr)与 R12(while 下标循环)未做,仍列为待办。全量 77/77 顺序回归通过。
233 lines
8.5 KiB
Plaintext
233 lines
8.5 KiB
Plaintext
from stdint import *
|
||
import w32.win32console
|
||
import t, c
|
||
from t import CInt, CExport
|
||
import stdio
|
||
import stdlib
|
||
import string
|
||
import memhub
|
||
import testcheck
|
||
|
||
|
||
def main() -> CInt | CExport:
|
||
w32.win32console.SetConsoleCP(65001)
|
||
w32.win32console.SetConsoleOutputCP(65001)
|
||
|
||
testcheck.begin("DictTest: 万能 dict (Variant 存储) 测试")
|
||
|
||
# 分配内存竞技场
|
||
arena: bytes = stdlib.malloc(65536)
|
||
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
|
||
|
||
# === Test 1: dict set_int / c.Deref 基本操作 ===
|
||
testcheck.section("Test 1: dict set_int / c.Deref 基本操作")
|
||
d: dict = dict(bd)
|
||
d.set_int("alpha", 10)
|
||
d.set_int("beta", 20)
|
||
d.set_int("gamma", 30)
|
||
n: sizet = len(d)
|
||
stdio.printf("len=%lu\n", n)
|
||
testcheck.check(n == 3, "dict len OK (3)", "dict len FAILED")
|
||
|
||
# dict 的 int 值按 int(i32)写入(见 _dict.vp set_int 的 int_ptr),读回须
|
||
# 给出有元素类型的指针:c.Deref 的宽度只认 pointee 类型,i8*(t.CPtr)恒读
|
||
# 1 字节,不再按赋值目标注解反推 4 字节。
|
||
p1: t.CPtr = d["alpha"]
|
||
stdio.printf("p1=%p\n", p1)
|
||
p2: t.CPtr = d["beta"]
|
||
stdio.printf("p2=%p\n", p2)
|
||
p3: t.CPtr = d["gamma"]
|
||
stdio.printf("p3=%p\n", p3)
|
||
v1: int = *(int | t.CPtr)(p1)
|
||
stdio.printf("v1=%d\n", v1)
|
||
v2: int = *(int | t.CPtr)(p2)
|
||
v3: int = *(int | t.CPtr)(p3)
|
||
stdio.printf("alpha=%d beta=%d gamma=%d\n", v1, v2, v3)
|
||
testcheck.check(v1 == 10, "dict[alpha]==10 OK", "dict[alpha] FAILED")
|
||
testcheck.check(v2 == 20, "dict[beta]==20 OK", "dict[beta] FAILED")
|
||
testcheck.check(v3 == 30, "dict[gamma]==30 OK", "dict[gamma] FAILED")
|
||
|
||
# === Test 2: 更新已有键 ===
|
||
testcheck.section("Test 2: 更新已有键")
|
||
d.set_int("beta", 99)
|
||
p2b: t.CPtr = d["beta"]
|
||
v2b: int = *(int | t.CPtr)(p2b)
|
||
stdio.printf("beta(updated)=%d\n", v2b)
|
||
testcheck.check(v2b == 99, "dict update OK", "dict update FAILED")
|
||
testcheck.check(len(d) == 3, "dict len still 3 OK", "dict len changed FAILED")
|
||
|
||
# === Test 3: get with default ===
|
||
testcheck.section("Test 3: get with default")
|
||
gv: t.CPtr = d.get("missing", None)
|
||
testcheck.check(gv == None, "dict get missing OK (None)", "dict get missing FAILED")
|
||
|
||
gp: t.CPtr = d.get("alpha", None)
|
||
ga: int = *(int | t.CPtr)(gp)
|
||
stdio.printf("get(alpha)=%d\n", ga)
|
||
testcheck.check(ga == 10, "dict get existing OK", "dict get existing FAILED")
|
||
|
||
# === Test 4: contains ===
|
||
testcheck.section("Test 4: contains")
|
||
has_alpha: int = d.contains("alpha")
|
||
has_missing: int = d.contains("missing")
|
||
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: 迭代器 for key in dict")
|
||
iter_count: int = 0
|
||
for key in d:
|
||
kp: t.CPtr = d[key]
|
||
val: int = *(int | t.CPtr)(kp)
|
||
stdio.printf("dict[%s]=%d\n", key, val)
|
||
iter_count += 1
|
||
testcheck.check(iter_count == 3, "dict iter OK (3)", "dict iter FAILED")
|
||
|
||
# === Test 6: dict set_str 字符串值 ===
|
||
testcheck.section("Test 6: dict set_str 字符串值")
|
||
d2: dict = dict(bd)
|
||
d2.set_str("name", "Alice")
|
||
d2.set_str("city", "Beijing")
|
||
d2.set_str("lang", "TransPyC")
|
||
n2: sizet = len(d2)
|
||
stdio.printf("d2 len=%lu\n", n2)
|
||
testcheck.check(n2 == 3, "dict set_str len OK (3)", "dict set_str len FAILED")
|
||
|
||
name_p: t.CPtr = d2["name"]
|
||
city_p: t.CPtr = d2["city"]
|
||
lang_p: t.CPtr = d2["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, "dict str name OK", "dict str name FAILED")
|
||
testcheck.check(string.strcmp(city, "Beijing") == 0, "dict str city OK", "dict str city FAILED")
|
||
testcheck.check(string.strcmp(lang, "TransPyC") == 0, "dict str lang OK", "dict str lang FAILED")
|
||
|
||
# === Test 7: dict[str] 迭代 ===
|
||
testcheck.section("Test 7: dict 迭代 (str values)")
|
||
str_iter_count: int = 0
|
||
for k in d2:
|
||
svp: t.CPtr = d2[k]
|
||
sv: str = svp
|
||
stdio.printf("d2[%s]=%s\n", k, sv)
|
||
str_iter_count += 1
|
||
testcheck.check(str_iter_count == 3, "dict str iter OK (3)", "dict str iter FAILED")
|
||
|
||
# === Test 8: 扩容测试 ===
|
||
testcheck.section("Test 8: 扩容测试 (>8 个元素)")
|
||
d3: dict = dict(bd)
|
||
i: int = 0
|
||
while i < 20:
|
||
key_buf: str = stdlib.malloc(16)
|
||
stdio.sprintf(key_buf, "key%d", i)
|
||
d3.set_int(key_buf, i * 100)
|
||
i += 1
|
||
n3: sizet = len(d3)
|
||
stdio.printf("d3 len=%lu (after 20 inserts)\n", n3)
|
||
testcheck.check(n3 == 20, "dict expand OK (20)", "dict expand FAILED")
|
||
|
||
# 验证几个值
|
||
k5: str = stdlib.malloc(16)
|
||
stdio.sprintf(k5, "key5")
|
||
p5: t.CPtr = d3[k5]
|
||
v5: int = *(int | t.CPtr)(p5)
|
||
stdio.printf("d3[key5]=%d\n", v5)
|
||
testcheck.check(v5 == 500, "dict expand key5 OK", "dict expand key5 FAILED")
|
||
|
||
k15: str = stdlib.malloc(16)
|
||
stdio.sprintf(k15, "key15")
|
||
p15: t.CPtr = d3[k15]
|
||
v15: int = *(int | t.CPtr)(p15)
|
||
stdio.printf("d3[key15]=%d\n", v15)
|
||
testcheck.check(v15 == 1500, "dict expand key15 OK", "dict expand key15 FAILED")
|
||
|
||
# === Test 9: JSON dumps ===
|
||
testcheck.section("Test 9: JSON dumps")
|
||
pool_mem: bytes = stdlib.malloc(65536)
|
||
pool: memhub.MemPool = memhub.MemPool(pool_mem, 65536)
|
||
|
||
jd: dict = dict(bd)
|
||
jd.set_int("x", 100)
|
||
jd.set_int("y", 200)
|
||
jd.set_int("z", 300)
|
||
|
||
json_str: str = jd.dumps(pool)
|
||
stdio.printf("JSON dumps: %s\n", json_str)
|
||
testcheck.check(json_str != None, "dumps OK", "dumps FAILED (null)")
|
||
|
||
# === Test 10: JSON loads ===
|
||
testcheck.section("Test 10: JSON loads")
|
||
jd2: dict = dict(bd)
|
||
jd2.loads(pool, "{\"x\":1,\"y\":2,\"z\":3}")
|
||
xp: t.CPtr = jd2["x"]
|
||
yp: t.CPtr = jd2["y"]
|
||
zp: t.CPtr = jd2["z"]
|
||
xv: int = *(int | t.CPtr)(xp)
|
||
yv: int = *(int | t.CPtr)(yp)
|
||
zv: int = *(int | t.CPtr)(zp)
|
||
stdio.printf("loads: x=%d y=%d z=%d\n", xv, yv, zv)
|
||
testcheck.check(xv == 1, "loads x OK", "loads x FAILED")
|
||
testcheck.check(yv == 2, "loads y OK", "loads y FAILED")
|
||
testcheck.check(zv == 3, "loads z OK", "loads z FAILED")
|
||
|
||
# === Test 11: JSON dumps (str values) ===
|
||
testcheck.section("Test 11: JSON dumps (str values)")
|
||
jd3: dict = dict(bd)
|
||
jd3.set_str("name", "Alice")
|
||
jd3.set_str("city", "Beijing")
|
||
|
||
json_str2: str = jd3.dumps(pool)
|
||
stdio.printf("JSON dumps (str): %s\n", json_str2)
|
||
testcheck.check(json_str2 != None, "dumps str OK", "dumps str FAILED (null)")
|
||
|
||
# === Test 12: JSON round-trip ===
|
||
testcheck.section("Test 12: JSON round-trip")
|
||
rt: dict = dict(bd)
|
||
rt.set_int("a", 1)
|
||
rt.set_int("b", 2)
|
||
rt_str: str = rt.dumps(pool)
|
||
stdio.printf("round-trip dump: %s\n", rt_str)
|
||
rt2: dict = dict(bd)
|
||
rt2.loads(pool, rt_str)
|
||
rta_p: t.CPtr = rt2["a"]
|
||
rtb_p: t.CPtr = rt2["b"]
|
||
rta: int = *(int | t.CPtr)(rta_p)
|
||
rtb: int = *(int | t.CPtr)(rtb_p)
|
||
stdio.printf("round-trip: a=%d b=%d\n", rta, rtb)
|
||
testcheck.check(rta == 1, "round-trip a OK", "round-trip a FAILED")
|
||
testcheck.check(rtb == 2, "round-trip b OK", "round-trip b FAILED")
|
||
|
||
# === Test 13: 嵌套 dict ===
|
||
testcheck.section("Test 13: 嵌套 dict")
|
||
outer: dict = dict(bd)
|
||
inner: dict = dict(bd)
|
||
inner.set_int("a", 1)
|
||
inner.set_int("b", 2)
|
||
outer.set_dict("sub", inner)
|
||
|
||
sub: dict* = outer["sub"]
|
||
sa_p: t.CPtr = sub["a"]
|
||
sb_p: t.CPtr = sub["b"]
|
||
sa: int = *(int | t.CPtr)(sa_p)
|
||
sb: int = *(int | t.CPtr)(sb_p)
|
||
stdio.printf("nested: sub.a=%d sub.b=%d\n", sa, sb)
|
||
testcheck.check(sa == 1, "nested sub.a OK", "nested sub.a FAILED")
|
||
testcheck.check(sb == 2, "nested sub.b OK", "nested sub.b FAILED")
|
||
|
||
# === Test 14: get_vtype 类型标签 ===
|
||
testcheck.section("Test 14: get_vtype 类型标签")
|
||
vt1: int = d.get_vtype("alpha")
|
||
vt2: int = d2.get_vtype("name")
|
||
vt3: int = outer.get_vtype("sub")
|
||
stdio.printf("vtype(alpha)=%d vtype(name)=%d vtype(sub)=%d\n", vt1, vt2, vt3)
|
||
testcheck.check(vt1 == 1, "vtype int OK", "vtype int FAILED")
|
||
testcheck.check(vt2 == 4, "vtype str OK", "vtype str FAILED")
|
||
testcheck.check(vt3 == 5, "vtype dict OK", "vtype dict FAILED")
|
||
|
||
stdlib.free(pool_mem)
|
||
stdlib.free(arena)
|
||
return testcheck.end()
|