#!/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())