v1.5.4 Bug 修复:模板文件名修正 + 布局重设计
BUG-005: 模板文件名改为 PinMAP-Template.xlsx / PinList-Template.xlsx BUG-006: 布局改为 Number 外侧 + Name 里侧(v1.5.4 最终版) - 从边界往中心:第1圈=Number,第2圈=Name - 上边角点例外处理,15种网格无冲突 - 18/18 单元测试 + 37/37 集成测试全部通过
This commit is contained in:
@@ -84,19 +84,27 @@ def create_pinmap_fixture(data: dict, path: str):
|
||||
def test_map_to_list(r: TestRunner):
|
||||
fixture_dir = os.path.join(os.path.dirname(__file__), 'fixtures')
|
||||
|
||||
# TC-MAP-001: 标准 4x4 PinMAP 转换
|
||||
# TC-MAP-001: 标准 4x4 PinMAP 转换 (v1.5.4 布局)
|
||||
def _tc_map_001(result):
|
||||
filepath = os.path.join(fixture_dir, 'sample_4x4.xlsx')
|
||||
cells = read_xlsx_cells(filepath)
|
||||
pinmap = parse_pinmap(cells)
|
||||
validation = validate_pinmap(pinmap)
|
||||
pinlist = generate_pinlist(pinmap, validation)
|
||||
assert pinlist.package_info, "package_info 不应为空"
|
||||
assert len(pinlist.rows) > 0, "应有引脚数据"
|
||||
# 封装信息 (v1.5.4 布局)
|
||||
assert pinlist.package_info == "QFP-16", f"封装应为 QFP-16,实际: {pinlist.package_info}"
|
||||
# 引脚数 (4x4 网格: (4+4)*2 = 16)
|
||||
assert len(pinlist.rows) == 16, f"应有 16 个引脚,实际: {len(pinlist.rows)}"
|
||||
# 验证递增排序
|
||||
nums = [num for _, num in pinlist.rows]
|
||||
assert nums == sorted(nums), f"序号应递增,实际: {nums}"
|
||||
result.ok(f"封装={pinlist.package_info}, Pin数={len(pinlist.rows)}, 序号递增")
|
||||
assert nums == list(range(1, 17)), f"序号应为 1-16,实际: {nums}"
|
||||
# 验证引脚名不是数字(确保 Name/Number 未错位)
|
||||
names = [name for name, _ in pinlist.rows]
|
||||
for name in names:
|
||||
assert not name.isdigit(), f"引脚名 '{name}' 不应为纯数字"
|
||||
assert all(name.startswith("Pin") for name in names), f"所有引脚名应以 Pin 开头: {names}"
|
||||
result.ok(f"封装={pinlist.package_info}, Pin数={len(pinlist.rows)}, 序号 1-16, 引脚名=Pin1..Pin16")
|
||||
|
||||
r.run("TC-MAP-001: 标准4x4 PinMAP转换", _tc_map_001)
|
||||
|
||||
@@ -570,19 +578,19 @@ def test_v15_styles(r: TestRunner):
|
||||
from xlsx_writer import write_xlsx_with_style
|
||||
|
||||
try:
|
||||
# ── TC-v1.5-001: MAP→List 加载 BallList 模板 ──
|
||||
# ── TC-v1.5-001: MAP→List 加载 PinList 模板 ──
|
||||
def _tc_v15_001(result):
|
||||
template_path = os.path.join(fixture_dir, 'BallList-Template.xlsx')
|
||||
assert os.path.exists(template_path), f"BallList 模板文件不存在: {template_path}"
|
||||
template_path = os.path.join(fixture_dir, 'PinList-Template.xlsx')
|
||||
assert os.path.exists(template_path), f"PinList 模板文件不存在: {template_path}"
|
||||
|
||||
style = read_template_styles(template_path)
|
||||
assert style is not None, "BallList 模板样式应成功读取"
|
||||
assert style is not None, "PinList 模板样式应成功读取"
|
||||
assert len(style.fonts) > 0, "应有字体定义"
|
||||
assert len(style.borders) > 0, "应有边框定义"
|
||||
assert 0 in style.column_widths, "应有列宽定义"
|
||||
result.ok(f"模板加载成功: fonts={len(style.fonts)}, borders={len(style.borders)}, width_A={style.column_widths.get(0)}")
|
||||
|
||||
r.run("TC-v1.5-001: MAP->List 加载 BallList 模板", _tc_v15_001)
|
||||
r.run("TC-v1.5-001: MAP->List 加载 PinList 模板", _tc_v15_001)
|
||||
|
||||
# ── TC-v1.5-002: MAP→List 无模板降级 ──
|
||||
def _tc_v15_002(result):
|
||||
@@ -592,19 +600,19 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
r.run("TC-v1.5-002: MAP->List 无模板降级", _tc_v15_002)
|
||||
|
||||
# ── TC-v1.5-003: List→MAP 加载 BallMAP 模板 ──
|
||||
# ── TC-v1.5-003: List→MAP 加载 PinMAP 模板 ──
|
||||
def _tc_v15_003(result):
|
||||
template_path = os.path.join(fixture_dir, 'BallMAP-Template.xlsx')
|
||||
assert os.path.exists(template_path), f"BallMAP 模板文件不存在: {template_path}"
|
||||
template_path = os.path.join(fixture_dir, 'PinMAP-Template.xlsx')
|
||||
assert os.path.exists(template_path), f"PinMAP 模板文件不存在: {template_path}"
|
||||
|
||||
style = read_template_styles(template_path)
|
||||
assert style is not None, "BallMAP 模板样式应成功读取"
|
||||
assert style is not None, "PinMAP 模板样式应成功读取"
|
||||
assert len(style.fonts) > 0, "应有字体定义"
|
||||
assert len(style.borders) > 0, "应有边框定义"
|
||||
assert 0 in style.row_heights, "应有行高定义"
|
||||
result.ok(f"模板加载成功: fonts={len(style.fonts)}, borders={len(style.borders)}, row_height={style.row_heights.get(0)}")
|
||||
|
||||
r.run("TC-v1.5-003: List->MAP 加载 BallMAP 模板", _tc_v15_003)
|
||||
r.run("TC-v1.5-003: List->MAP 加载 PinMAP 模板", _tc_v15_003)
|
||||
|
||||
# ── TC-v1.5-004: List→MAP 无模板降级 ──
|
||||
def _tc_v15_004(result):
|
||||
@@ -616,19 +624,19 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
# ── TC-v1.5-005: 两个方向独立使用各自模板 ──
|
||||
def _tc_v15_005(result):
|
||||
bl_path = os.path.join(fixture_dir, 'BallList-Template.xlsx')
|
||||
bm_path = os.path.join(fixture_dir, 'BallMAP-Template.xlsx')
|
||||
bl_path = os.path.join(fixture_dir, 'PinList-Template.xlsx')
|
||||
bm_path = os.path.join(fixture_dir, 'PinMAP-Template.xlsx')
|
||||
|
||||
style_bl = read_template_styles(bl_path)
|
||||
style_bm = read_template_styles(bm_path)
|
||||
|
||||
assert style_bl is not None, "BallList 模板应成功加载"
|
||||
assert style_bm is not None, "BallMAP 模板应成功加载"
|
||||
assert style_bl is not None, "PinList 模板应成功加载"
|
||||
assert style_bm is not None, "PinMAP 模板应成功加载"
|
||||
|
||||
# BallList 有列宽,BallMAP 有行高
|
||||
assert 0 in style_bl.column_widths, "BallList 应有列宽"
|
||||
assert 0 in style_bm.row_heights, "BallMAP 应有行高"
|
||||
result.ok(f"两个模板独立: BL fonts={len(style_bl.fonts)}, BM fonts={len(style_bm.fonts)}")
|
||||
# PinList 有列宽,PinMAP 有行高
|
||||
assert 0 in style_bl.column_widths, "PinList 应有列宽"
|
||||
assert 0 in style_bm.row_heights, "PinMAP 应有行高"
|
||||
result.ok(f"两个模板独立: PL fonts={len(style_bl.fonts)}, PM fonts={len(style_bm.fonts)}")
|
||||
|
||||
r.run("TC-v1.5-005: 两个方向独立使用各自模板", _tc_v15_005)
|
||||
|
||||
@@ -645,7 +653,7 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
# ── TC-v1.5-007: 模板字体应用到输出文件 ──
|
||||
def _tc_v15_007(result):
|
||||
template_path = os.path.join(fixture_dir, 'BallMAP-Template.xlsx')
|
||||
template_path = os.path.join(fixture_dir, 'PinMAP-Template.xlsx')
|
||||
style = read_template_styles(template_path)
|
||||
|
||||
assert style is not None, "模板样式应成功读取"
|
||||
@@ -669,7 +677,7 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
# ── TC-v1.5-008: 模板列宽应用到输出文件 ──
|
||||
def _tc_v15_008(result):
|
||||
template_path = os.path.join(fixture_dir, 'BallList-Template.xlsx')
|
||||
template_path = os.path.join(fixture_dir, 'PinList-Template.xlsx')
|
||||
style = read_template_styles(template_path)
|
||||
assert style is not None, "模板样式应成功读取"
|
||||
|
||||
@@ -700,7 +708,7 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
# ── TC-v1.5-009: 模板行高应用到输出文件 ──
|
||||
def _tc_v15_009(result):
|
||||
template_path = os.path.join(fixture_dir, 'BallMAP-Template.xlsx')
|
||||
template_path = os.path.join(fixture_dir, 'PinMAP-Template.xlsx')
|
||||
style = read_template_styles(template_path)
|
||||
assert style is not None, "模板样式应成功读取"
|
||||
|
||||
@@ -732,19 +740,19 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
# ── TC-v1.5-010: 两个方向使用不同模板各自的格式 ──
|
||||
def _tc_v15_010(result):
|
||||
bl_path = os.path.join(fixture_dir, 'BallList-Template.xlsx')
|
||||
bm_path = os.path.join(fixture_dir, 'BallMAP-Template.xlsx')
|
||||
bl_path = os.path.join(fixture_dir, 'PinList-Template.xlsx')
|
||||
bm_path = os.path.join(fixture_dir, 'PinMAP-Template.xlsx')
|
||||
|
||||
style_bl = read_template_styles(bl_path)
|
||||
style_bm = read_template_styles(bm_path)
|
||||
assert style_bl and style_bm, "两个模板都应该成功加载"
|
||||
|
||||
# MAP->List 方向:用 BallList 模板
|
||||
# MAP->List 方向:用 PinList 模板
|
||||
pinlist_data = {'A1': 'QFP-44', 'A2': 'Pin1', 'B2': '1'}
|
||||
pinlist_path = os.path.join(tmpdir, 'v15_010_pinlist.xlsx')
|
||||
write_xlsx_with_style(pinlist_data, pinlist_path, style_bl)
|
||||
|
||||
# List->MAP 方向:用 BallMAP 模板
|
||||
# List->MAP 方向:用 PinMAP 模板
|
||||
entries = [PinListEntry(number=i+1, name=f"PIN{i+1:02d}") for i in range(12)]
|
||||
pinmap_path = os.path.join(tmpdir, 'v15_010_pinmap.xlsx')
|
||||
generate_pinmap(entries, 3, 3, "QFP-12", template_style=style_bm, output_path=pinmap_path)
|
||||
@@ -755,17 +763,17 @@ def test_v15_styles(r: TestRunner):
|
||||
with zipfile.ZipFile(pinmap_path, 'r') as zf:
|
||||
pm_styles = zf.read('xl/styles.xml').decode('utf-8')
|
||||
|
||||
assert '楷体' in pl_styles, "BallList 输出应包含楷体"
|
||||
assert '宋体' in pm_styles, "BallMAP 输出应包含宋体"
|
||||
assert '楷体' in pl_styles, "PinList 输出应包含楷体"
|
||||
assert '宋体' in pm_styles, "PinMAP 输出应包含宋体"
|
||||
|
||||
result.ok("两个方向输出字体不同: BL->楷体, BM->宋体")
|
||||
result.ok("两个方向输出字体不同: PinList->楷体, PinMAP->宋体")
|
||||
|
||||
r.run("TC-v1.5-010: 两个方向不同模板各自的格式", _tc_v15_010)
|
||||
|
||||
# ── TC-v1.5-011: 完整往返+模板隔离 ──
|
||||
# ── TC-v1.5-011: 完整往返+模板隔离 (4×4 网格) ──
|
||||
def _tc_v15_011(result):
|
||||
bl_path = os.path.join(fixture_dir, 'BallList-Template.xlsx')
|
||||
bm_path = os.path.join(fixture_dir, 'BallMAP-Template.xlsx')
|
||||
bl_path = os.path.join(fixture_dir, 'PinList-Template.xlsx')
|
||||
bm_path = os.path.join(fixture_dir, 'PinMAP-Template.xlsx')
|
||||
|
||||
style_bl = read_template_styles(bl_path)
|
||||
style_bm = read_template_styles(bm_path)
|
||||
@@ -786,7 +794,8 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
pkg2, entries2 = parse_pinlist(pinlist_path)
|
||||
pinmap_path = os.path.join(tmpdir, 'v15_011_pinmap.xlsx')
|
||||
generate_pinmap(entries2, 3, 3, pkg2, template_style=style_bm, output_path=pinmap_path)
|
||||
# 4×4 网格: (4+4)×2 = 16 引脚
|
||||
generate_pinmap(entries2, 4, 4, pkg2, template_style=style_bm, output_path=pinmap_path)
|
||||
|
||||
rt_cells = read_xlsx_cells(pinmap_path)
|
||||
rt_pinmap = parse_pinmap(rt_cells)
|
||||
@@ -800,8 +809,8 @@ def test_v15_styles(r: TestRunner):
|
||||
pl_xml = zf.read('xl/styles.xml').decode('utf-8')
|
||||
with zipfile.ZipFile(pinmap_path, 'r') as zf:
|
||||
pm_xml = zf.read('xl/styles.xml').decode('utf-8')
|
||||
assert '楷体' in pl_xml, "中间 PinList 应使用 BallList 的楷体"
|
||||
assert '宋体' in pm_xml, "最终 PinMAP 应使用 BallMAP 的宋体"
|
||||
assert '楷体' in pl_xml, "中间 PinList 应使用 PinList 模板的楷体"
|
||||
assert '宋体' in pm_xml, "最终 PinMAP 应使用 PinMAP 模板的宋体"
|
||||
|
||||
result.ok(f"往返成功: {len(pinmap.pins)} pins, 楷体->PinList, 宋体->PinMAP")
|
||||
|
||||
@@ -828,7 +837,8 @@ def test_v15_styles(r: TestRunner):
|
||||
|
||||
pkg2, entries2 = parse_pinlist(pinlist_path)
|
||||
pinmap_path = os.path.join(tmpdir, 'v15_012_pinmap.xlsx')
|
||||
generate_pinmap(entries2, 3, 3, pkg2, template_style=None, output_path=pinmap_path)
|
||||
# sample_4x4 有 16 pins,需用 4×4 网格
|
||||
generate_pinmap(entries2, 4, 4, pkg2, template_style=None, output_path=pinmap_path)
|
||||
assert os.path.exists(pinmap_path), "PinMAP 输出文件应存在"
|
||||
|
||||
result.ok("无模板完整流程正常")
|
||||
|
||||
Reference in New Issue
Block a user