"""对码引擎单测:不依赖 DB / Oracle,纯内存验证四要素匹配 + 规格标准化。 运行: python -m pytest state_center/tests/test_match_engine.py -v 或直接: python state_center/tests/test_match_engine.py """ import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) from state_center.app.match_engine import ( # noqa: E402 MatchEngine, GoodsRecord, build_match_key, _norm_spec, ) def _engine(): eng = MatchEngine() eng.load_goods([ GoodsRecord("阿卡波糖片", "国药准字H19990001", "50mg*30", "盒", "拜耳医药", "G001", "C001"), GoodsRecord("哈药牌钙铁锌口服液", "国药准字Z20000002", "10ml*10", "盒", "哈药集团", "G002", "C002"), # 同名多规格(用于一对多) GoodsRecord("阿卡波糖片", "国药准字H19990001", "50mg*60", "盒", "拜耳医药", "G003", "C003"), ]) return eng def test_spec_normalize_product(): # 15×2 展开成 30 assert _norm_spec("15×2") == _norm_spec("15*2") assert _norm_spec("50mg*30").startswith("1500") or "mg" in _norm_spec("50mg*30") def test_exact_hit(): eng = _engine() r = eng.match_one(1, "哈药牌钙铁锌口服液", "国药准字Z20000002", "10ml*10", "哈药集团") assert r.match_status == "EXACT" assert r.goods_id == "G002" def test_multi_same_name(): eng = _engine() # 规格写法对不上任何精确键,但商品名命中多条 → MULTI r = eng.match_one(2, "阿卡波糖片", "国药准字H19990001", "写个对不上的规格", "拜耳医药") assert r.match_status == "MULTI" assert len(r.candidates) >= 2 def test_none(): eng = _engine() r = eng.match_one(3, "不存在的药", "X", "1", "无") assert r.match_status == "NONE" def test_alias_priority(): eng = _engine() key = build_match_key("阿卡波糖", "", "30片", "") # 平台奇葩写法 eng.load_aliases({key: ("G001", "C001", "盒")}) r = eng.match_one(4, "阿卡波糖", "", "30片", "") assert r.match_status == "ALIAS" assert r.goods_id == "G001" def test_manufacturer_tolerance(): # 进口英文厂家:大小写/标点容错 k1 = build_match_key("药A", "H1", "1", "Abbott Biologicals B.V.") k2 = build_match_key("药A", "H1", "1", "abbott biologicals bv") assert k1 == k2 if __name__ == "__main__": import traceback fns = [v for k, v in sorted(globals().items()) if k.startswith("test_")] passed = 0 for fn in fns: try: fn() print(f"PASS {fn.__name__}") passed += 1 except Exception: print(f"FAIL {fn.__name__}") traceback.print_exc() print(f"\n{passed}/{len(fns)} passed")