签入版本

This commit is contained in:
2026-09-12 17:39:13 +08:00
parent 25c8b039ac
commit 3233d221b0
871 changed files with 103088 additions and 10561 deletions
+102
View File
@@ -0,0 +1,102 @@
"""dict_util 字典读取工具:列表/映射/单值读取,进程内缓存与失效行为。"""
from types import SimpleNamespace
from utils import dict_util
from utils.dict_util import (
get_dict_items,
get_dict_label,
get_dict_map,
invalidate_dict,
invalidate_dicts_by_ids,
)
def _clear_cache():
dict_util._dict_cache.clear()
def _rows():
# 刻意乱序:女(sort=5)、男(sort=1)、保密(sort=10),校验按 sort+id 升序输出
return [
SimpleNamespace(id=2, name='女', value='2', sort=5),
SimpleNamespace(id=1, name='男', value='1', sort=1),
SimpleNamespace(id=3, name='保密', value='3', sort=10),
]
class _FakeQuery:
def __init__(self, rows):
self._rows = rows
def all(self):
return self._rows
def _patch_repo(monkeypatch, dict_obj):
monkeypatch.setattr(dict_util.dict_repo, 'get_one', lambda **kw: dict_obj)
monkeypatch.setattr(dict_util.dictitem_repo, 'filter_by', lambda **kw: _FakeQuery(_rows()))
# ============ 读取 ============
def test_get_dict_map_maps_value_to_label(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, SimpleNamespace(id=1, code='gender', name='性别'))
assert get_dict_map('gender') == {'1': '男', '2': '女', '3': '保密'}
def test_get_dict_items_sorted_by_sort_then_id(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, SimpleNamespace(id=1, code='gender', name='性别'))
assert [it['value'] for it in get_dict_items('gender')] == ['1', '2', '3']
def test_get_dict_label_normalizes_value_to_str(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, SimpleNamespace(id=1, code='gender', name='性别'))
# 用户存整数 1,字典项 value 是字符串 '1',需自动转字符串匹配
assert get_dict_label('gender', 1) == '男'
assert get_dict_label('gender', '2') == '女'
assert get_dict_label('gender', 99) is None
assert get_dict_label('gender', 99, '未知') == '未知'
def test_get_dict_map_unknown_code_returns_empty(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, None)
assert get_dict_items('nope') == []
assert get_dict_map('nope') == {}
# ============ 缓存 ============
def test_cache_hit_skips_db(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, SimpleNamespace(id=1, code='gender', name='性别'))
get_dict_map('gender')
calls = []
monkeypatch.setattr(dict_util.dict_repo, 'get_one', lambda **kw: calls.append(1) or None)
get_dict_map('gender') # 命中缓存,不再访问 DB
assert calls == []
def test_invalidate_dict_clears_cache(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, SimpleNamespace(id=1, code='gender', name='性别'))
get_dict_map('gender')
invalidate_dict('gender')
assert dict_util._dict_cache == {}
def test_invalidate_dicts_by_ids_clears_cached_codes(monkeypatch):
_clear_cache()
_patch_repo(monkeypatch, SimpleNamespace(id=1, code='gender', name='性别'))
get_dict_map('gender') # 先填充缓存
class _FakeRows:
def all(self):
return [SimpleNamespace(code='gender')]
monkeypatch.setattr(dict_util.dict_repo, 'filter', lambda *criteria: _FakeRows())
invalidate_dicts_by_ids({1})
assert dict_util._dict_cache == {}