survey_custom_certificate_t.../tests/test_property_placeholder_extraction_standalone.py
2025-11-29 08:46:04 +07:00

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())