签入版本
This commit is contained in:
@@ -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 == {}
|
||||
Reference in New Issue
Block a user