test: add comprehensive pytest test suite
Add complete test infrastructure for yaml2pptx project with 245+ tests covering unit, integration, and end-to-end scenarios. Test structure: - Unit tests: elements, template system, validators, loaders, utils - Integration tests: presentation and rendering flows - E2E tests: CLI commands (convert, check, preview) Key features: - PptxFileValidator for Level 2 PPTX validation (file structure, element count, content matching, position tolerance) - Comprehensive fixtures for test data consistency - Mock-based testing for external dependencies - Test images generated with PIL/Pillow - Boundary case coverage for edge scenarios Dependencies added: - pytest, pytest-cov, pytest-mock - pillow (for test image generation) Documentation updated: - README.md: test running instructions - README_DEV.md: test development guide Co-authored-by: OpenSpec change: add-comprehensive-tests
This commit is contained in:
128
tests/unit/test_validators/test_geometry.py
Normal file
128
tests/unit/test_validators/test_geometry.py
Normal file
@@ -0,0 +1,128 @@
|
||||
"""
|
||||
几何验证器单元测试
|
||||
|
||||
测试 GeometryValidator 的元素边界检查功能
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from validators.geometry import GeometryValidator, TOLERANCE
|
||||
from validators.result import ValidationIssue
|
||||
|
||||
|
||||
class TestGeometryValidator:
|
||||
"""GeometryValidator 测试类"""
|
||||
|
||||
def test_init(self):
|
||||
"""测试初始化"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
assert validator.slide_width == 10
|
||||
assert validator.slide_height == 5.625
|
||||
|
||||
def test_validate_element_within_bounds(self):
|
||||
"""测试元素在边界内"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'box': [1, 1, 5, 2]
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 0
|
||||
|
||||
def test_validate_element_right_boundary_exceeded(self):
|
||||
"""测试元素右边界超出"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'box': [8, 1, 3, 1] # right = 11 > 10
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 1
|
||||
assert issues[0].level == "WARNING"
|
||||
assert issues[0].code == "ELEMENT_OUT_OF_BOUNDS"
|
||||
assert "右边界" in issues[0].message
|
||||
|
||||
def test_validate_element_bottom_boundary_exceeded(self):
|
||||
"""测试元素下边界超出"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'box': [1, 5, 2, 1] # bottom = 6 > 5.625
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 1
|
||||
assert issues[0].level == "WARNING"
|
||||
assert issues[0].code == "ELEMENT_OUT_OF_BOUNDS"
|
||||
assert "下边界" in issues[0].message
|
||||
|
||||
def test_validate_element_completely_out_of_bounds(self):
|
||||
"""测试元素完全在页面外"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'box': [12, 7, 2, 1] # 完全在页面外
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 1
|
||||
assert issues[0].level == "WARNING"
|
||||
assert issues[0].code == "ELEMENT_COMPLETELY_OUT_OF_BOUNDS"
|
||||
|
||||
def test_validate_element_within_tolerance(self):
|
||||
"""测试元素在容忍度范围内"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
# 右边界 = 10.05,容忍度 0.1,应该通过
|
||||
elem = type('Element', (), {
|
||||
'box': [8, 1, 2.05, 1]
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 0
|
||||
|
||||
def test_validate_element_slightly_beyond_tolerance(self):
|
||||
"""测试元素稍微超出容忍度"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
# 右边界 = 10.15,超出容忍度 0.1
|
||||
elem = type('Element', (), {
|
||||
'box': [8, 1, 2.15, 1]
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 1
|
||||
|
||||
def test_validate_table_within_bounds(self):
|
||||
"""测试表格在边界内"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'position': [1, 1],
|
||||
'col_widths': [2, 2, 2]
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 0
|
||||
|
||||
def test_validate_table_exceeds_width(self):
|
||||
"""测试表格超出页面宽度"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'position': [1, 1],
|
||||
'col_widths': [3, 3, 4] # 总宽 10,位置 1,右边界 11
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 1
|
||||
assert issues[0].code == "TABLE_OUT_OF_BOUNDS"
|
||||
|
||||
def test_validate_element_without_box(self):
|
||||
"""测试没有 box 属性的元素"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {})() # 没有 box 属性
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 0
|
||||
|
||||
def test_validate_table_without_col_widths(self):
|
||||
"""测试没有 col_widths 的表格"""
|
||||
validator = GeometryValidator(10, 5.625)
|
||||
elem = type('Element', (), {
|
||||
'position': [1, 1]
|
||||
})()
|
||||
issues = validator.validate_element(elem, 1, 1)
|
||||
assert len(issues) == 0
|
||||
|
||||
|
||||
class TestToleranceConstant:
|
||||
"""容忍度常量测试"""
|
||||
|
||||
def test_tolerance_value(self):
|
||||
"""测试容忍度值为 0.1"""
|
||||
assert TOLERANCE == 0.1
|
||||
Reference in New Issue
Block a user