134 lines
4.3 KiB
Python
134 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Standalone property-based test for placeholder extraction completeness.
|
|
|
|
This test can run without the full Odoo environment by importing the parser
|
|
service directly from the local module structure.
|
|
|
|
Feature: survey-custom-certificate-template, Property 3: Placeholder extraction completeness
|
|
Validates: Requirements 2.1
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
|
|
# Add parent directory to path to import services
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
try:
|
|
from hypothesis import given, settings, HealthCheck
|
|
HYPOTHESIS_AVAILABLE = True
|
|
except ImportError:
|
|
print("ERROR: Hypothesis is not installed. Install with: pip install hypothesis")
|
|
sys.exit(1)
|
|
|
|
try:
|
|
from docx import Document
|
|
DOCX_AVAILABLE = True
|
|
except ImportError:
|
|
print("ERROR: python-docx is not installed. Install with: pip install python-docx")
|
|
sys.exit(1)
|
|
|
|
# Import the parser service directly
|
|
from services.certificate_template_parser import CertificateTemplateParser
|
|
|
|
# Import our custom strategies
|
|
from hypothesis_strategies import docx_with_placeholders
|
|
|
|
|
|
def test_property_3_placeholder_extraction_completeness():
|
|
"""
|
|
Feature: survey-custom-certificate-template, Property 3: Placeholder extraction completeness
|
|
|
|
For any DOCX template containing placeholders matching the {key.*} pattern,
|
|
the Template Parser should extract and return all such placeholders without omission.
|
|
|
|
Validates: Requirements 2.1
|
|
|
|
This property test verifies that:
|
|
1. All placeholders present in the generated DOCX are extracted
|
|
2. No placeholders are missed during parsing
|
|
3. The extraction is complete regardless of document structure
|
|
"""
|
|
print("\nTesting Property 3: Placeholder extraction completeness")
|
|
print("=" * 60)
|
|
|
|
parser = CertificateTemplateParser()
|
|
test_count = 0
|
|
|
|
@given(docx_data=docx_with_placeholders(min_placeholders=1, max_placeholders=10))
|
|
@settings(
|
|
max_examples=100,
|
|
deadline=None,
|
|
suppress_health_check=[HealthCheck.function_scoped_fixture]
|
|
)
|
|
def check_completeness(docx_data):
|
|
nonlocal test_count
|
|
test_count += 1
|
|
|
|
docx_binary, expected_placeholders = docx_data
|
|
|
|
# Parse the template to extract placeholders
|
|
extracted_placeholders = parser.parse_template(docx_binary)
|
|
|
|
# Convert to sets for comparison (order doesn't matter)
|
|
expected_set = set(expected_placeholders)
|
|
extracted_set = set(extracted_placeholders)
|
|
|
|
# Property: All expected placeholders should be extracted
|
|
if expected_set != extracted_set:
|
|
missing = expected_set - extracted_set
|
|
extra = extracted_set - expected_set
|
|
raise AssertionError(
|
|
f"Placeholder extraction incomplete.\n"
|
|
f"Expected: {expected_set}\n"
|
|
f"Extracted: {extracted_set}\n"
|
|
f"Missing: {missing}\n"
|
|
f"Extra: {extra}"
|
|
)
|
|
|
|
# Additional check: The count should match
|
|
if len(expected_placeholders) != len(extracted_placeholders):
|
|
raise AssertionError(
|
|
f"Placeholder count mismatch. "
|
|
f"Expected {len(expected_placeholders)} unique placeholders, "
|
|
f"but extracted {len(extracted_placeholders)}"
|
|
)
|
|
|
|
try:
|
|
check_completeness()
|
|
print(f"✓ Property 3 verified across {test_count} test cases")
|
|
print(" All placeholders were correctly extracted from all generated DOCX files")
|
|
return True
|
|
except Exception as e:
|
|
print(f"✗ Property 3 FAILED after {test_count} test cases")
|
|
print(f" Error: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
def main():
|
|
"""Run the property test."""
|
|
print("=" * 60)
|
|
print("Property-Based Test: Placeholder Extraction Completeness")
|
|
print("=" * 60)
|
|
|
|
success = test_property_3_placeholder_extraction_completeness()
|
|
|
|
print("\n" + "=" * 60)
|
|
if success:
|
|
print("✓ Property test PASSED")
|
|
print("=" * 60)
|
|
return 0
|
|
else:
|
|
print("✗ Property test FAILED")
|
|
print("=" * 60)
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|