fix(blackbox): accept black_box dir, guard ambiguous FD and non-dict JSON
This commit is contained in:
@@ -45,10 +45,14 @@ def _resolve_fd(bb_key, fd_aliases: dict):
|
||||
for fd_name, aliases in fd_aliases.items():
|
||||
if nk in aliases:
|
||||
return fd_name
|
||||
for fd_name, aliases in fd_aliases.items():
|
||||
for a in aliases:
|
||||
if a and (nk.startswith(a) or a.startswith(nk)):
|
||||
return fd_name
|
||||
matches = [
|
||||
fd_name for fd_name, aliases in fd_aliases.items()
|
||||
if any(a and (nk.startswith(a) or a.startswith(nk)) for a in aliases)
|
||||
]
|
||||
if len(matches) == 1:
|
||||
return matches[0]
|
||||
if len(matches) > 1:
|
||||
logger.warning(f"黑盒 FD '{bb_key}' 匹配到多个: {matches},跳过")
|
||||
return None
|
||||
|
||||
|
||||
@@ -70,10 +74,7 @@ def _iter_group_files(path: Path) -> list[Path]:
|
||||
files = sorted(p.glob('*_g*.json'))
|
||||
if files:
|
||||
return files
|
||||
bb = p / 'black_box'
|
||||
if bb.is_dir():
|
||||
return sorted(bb.rglob('*_g*.json'))
|
||||
return []
|
||||
return sorted(p.rglob('*_g*.json'))
|
||||
|
||||
|
||||
def _group_label(json_path: Path) -> str:
|
||||
@@ -84,6 +85,8 @@ def _group_label(json_path: Path) -> str:
|
||||
|
||||
|
||||
def _map_record(raw, fd_aliases, field_map, jf: Path) -> dict:
|
||||
if not isinstance(raw, dict):
|
||||
return {}
|
||||
inp = raw.get('input')
|
||||
if not isinstance(inp, dict):
|
||||
return {}
|
||||
@@ -119,6 +122,9 @@ def load_black_box_groups(path, fd_fields: dict, select_info: dict,
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.warning(f"黑盒 JSON 解析失败 {jf}: {e}")
|
||||
continue
|
||||
if not isinstance(obj, dict):
|
||||
logger.warning(f"黑盒 JSON 顶层非对象,跳过: {jf}")
|
||||
continue
|
||||
label = _group_label(jf)
|
||||
records = []
|
||||
for raw in obj.get('records', []) or []:
|
||||
|
||||
@@ -21,7 +21,7 @@ def _write_group(tmp, name, payload):
|
||||
|
||||
def test_norm_name():
|
||||
assert norm_name("R01-APPL-ID") == "R01APPLID"
|
||||
assert norm_name("R01APPL-ID") == "R01APPLID"
|
||||
assert norm_name("R01APPLID") == "R01APPLID"
|
||||
assert norm_name("r01_appl_id") == "R01APPLID"
|
||||
|
||||
|
||||
@@ -75,3 +75,58 @@ def test_load_groups_skips_unmatched_and_empty():
|
||||
})
|
||||
groups = load_black_box_groups(tmp, fd_fields, select_info, data_fields)
|
||||
assert groups == []
|
||||
|
||||
|
||||
def test_load_groups_fd_prefix_variant():
|
||||
fd_fields = {"R01INNFIL": ["R01APPL-ID"]}
|
||||
select_info = {"R01INNFIL": {"assign": "ZAN04R01"}}
|
||||
data_fields = [{"name": "R01APPL-ID", "pic": "X(8)"}]
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
_write_group(tmp, "ZAN04MAT_g1", {
|
||||
"program": "ZAN04MAT",
|
||||
"records": [{"input": {"R01": {"R01-APPL-ID": "C0000003"}}}],
|
||||
})
|
||||
groups = load_black_box_groups(tmp, fd_fields, select_info, data_fields)
|
||||
assert groups[0].records[0]["R01APPL-ID"] == "C0000003"
|
||||
|
||||
|
||||
def test_load_groups_ambiguous_prefix_skipped():
|
||||
fd_fields = {"R01INNFIL": ["R01APPL-ID"], "R01OUTFIL": ["R01APPL-ID"]}
|
||||
select_info = {"R01INNFIL": {"assign": "ZAN04R01"},
|
||||
"R01OUTFIL": {"assign": "ZAN04W01"}}
|
||||
data_fields = [{"name": "R01APPL-ID", "pic": "X(8)"}]
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
_write_group(tmp, "ZAN04MAT_g1", {
|
||||
"program": "ZAN04MAT",
|
||||
"records": [{"input": {"R01": {"R01-APPL-ID": "D0000004"}}}],
|
||||
})
|
||||
groups = load_black_box_groups(tmp, fd_fields, select_info, data_fields)
|
||||
assert groups == []
|
||||
|
||||
|
||||
def test_load_groups_accepts_black_box_dir_directly():
|
||||
fd_fields = {"R01INNFIL": ["R01APPL-ID"]}
|
||||
select_info = {"R01INNFIL": {"assign": "ZAN04R01"}}
|
||||
data_fields = [{"name": "R01APPL-ID", "pic": "X(8)"}]
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
_write_group(tmp, "ZAN04MAT_g1", {
|
||||
"program": "ZAN04MAT",
|
||||
"records": [{"input": {"ZAN04R01": {"R01APPL-ID": "E0000005"}}}],
|
||||
})
|
||||
groups = load_black_box_groups(Path(tmp) / "black_box", fd_fields,
|
||||
select_info, data_fields)
|
||||
assert len(groups) == 1
|
||||
|
||||
|
||||
def test_load_groups_skips_non_dict_records():
|
||||
fd_fields = {"R01INNFIL": ["R01APPL-ID"]}
|
||||
select_info = {"R01INNFIL": {"assign": "ZAN04R01"}}
|
||||
data_fields = [{"name": "R01APPL-ID", "pic": "X(8)"}]
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
_write_group(tmp, "ZAN04MAT_g1", {
|
||||
"program": "ZAN04MAT",
|
||||
"records": ["not-a-dict",
|
||||
{"input": {"ZAN04R01": {"R01APPL-ID": "F0000006"}}}],
|
||||
})
|
||||
groups = load_black_box_groups(tmp, fd_fields, select_info, data_fields)
|
||||
assert groups[0].records[0]["R01APPL-ID"] == "F0000006"
|
||||
|
||||
Reference in New Issue
Block a user