Files
markitect-main/tests/test_issue_65_template_parser.py
tegwick bcbe78d04f feat: Complete Issue #65 Template Engine Foundation + Fix CLI Regression
## Issue #65 - Template Engine Foundation (COMPLETED)
- Implement complete TDD8 methodology with 30 comprehensive tests (100% passing)
- Add template variable parser with Unicode and dot notation support
- Add template rendering engine with strict/lenient modes
- Add business document generation (invoices, reports)
- Add CLI integration with `markitect template-render` command
- Add performance optimization (1000+ variables in <0.1s)

## Critical CLI Regression Fix
- Fix broken `markitect --help` due to import path issues in markitect/issues/base.py
- Add proper path resolution for domain module accessibility
- Add 12 comprehensive CLI integration tests to prevent future regressions
- Restore full CLI functionality with 35+ working commands

## Template Engine Architecture
- markitect/template/parser.py - Variable parsing with comprehensive validation
- markitect/template/engine.py - Template rendering with business logic
- markitect/template/__init__.py - Structured package exports
- Comprehensive exception hierarchy for robust error handling

## Test Coverage Excellence
- 30 Issue #65 tests: parser (9), substitution (14), integration (7)
- 12 CLI integration tests for regression prevention
- Business scenario validation with real invoice/report generation
- Performance benchmarking and error handling validation

## CLI Professional Enhancement
- Add template-render command with comprehensive options
- Fix import path issues preventing CLI access
- Add validation, data checking, output options
- Support JSON/YAML data formats with auto-detection

## Business Impact
- Transform MarkiTect from document analysis to business automation platform
- Enable professional invoice and report generation
- Provide robust CLI interface for document workflows
- Establish foundation for Epic #64 advanced template features

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 15:33:32 +02:00

222 lines
7.3 KiB
Python

"""
Test for Issue #65: Template Engine Foundation - Template Variable Parser
This test module validates the core template variable parsing functionality
for the MarkiTect template engine, implementing TDD8 Cycle 1.
Tests focus on:
- Basic variable parsing from template strings
- Nested object variable extraction
- Markdown structure preservation during parsing
"""
import pytest
from typing import List, Set
class TestTemplateVariableParser:
"""Test suite for template variable parsing functionality."""
def setup_method(self):
"""Set up test environment for each test."""
# Import the template parser (will be implemented)
# For now, this will fail - following TDD RED phase
try:
from markitect.template.parser import TemplateParser
self.parser = TemplateParser()
except ImportError:
# Expected to fail initially - TDD RED phase
self.parser = None
def test_parse_simple_variables(self):
"""Test basic variable parsing from template strings.
Reference: Issue #65 - Template Engine Foundation
TDD Phase: RED (test should fail initially)
"""
# Arrange
template_text = "Hello {{name}}, welcome to {{company}}!"
expected_variables = {"name", "company"}
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert isinstance(variables, (list, set))
assert set(variables) == expected_variables
def test_parse_nested_variables(self):
"""Test nested object variable parsing with dot notation.
Reference: Issue #65 - Template Engine Foundation
TDD Phase: RED (test should fail initially)
"""
# Arrange
template_text = "Customer: {{customer.name}}, Email: {{customer.contact.email}}"
expected_variables = {"customer.name", "customer.contact.email"}
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
def test_parse_markdown_with_variables(self):
"""Test variable parsing from markdown content while preserving structure.
Reference: Issue #65 - Template Engine Foundation
TDD Phase: RED (test should fail initially)
"""
# Arrange
template_text = """---
title: "Invoice {{invoice_number}}"
customer: "{{customer.name}}"
---
# Invoice {{invoice_number}}
**Bill To**: {{customer.name}}
**Email**: {{customer.email}}
**Total**: {{total}} {{currency}}
## Line Items
| Description | Amount |
|-------------|--------|
| Service | {{service.amount}} |
"""
expected_variables = {
"invoice_number",
"customer.name",
"customer.email",
"total",
"currency",
"service.amount"
}
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
def test_parse_duplicate_variables(self):
"""Test that duplicate variables are handled correctly.
Reference: Issue #65 - Template Engine Foundation
"""
# Arrange
template_text = "{{name}} says hello to {{name}} and {{company}}"
expected_variables = {"name", "company"}
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
def test_parse_empty_template(self):
"""Test parsing template with no variables.
Reference: Issue #65 - Template Engine Foundation
"""
# Arrange
template_text = "This is a regular markdown document with no variables."
expected_variables = set()
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
def test_parse_malformed_variables(self):
"""Test handling of malformed variable syntax.
Reference: Issue #65 - Template Engine Foundation
"""
# Arrange
template_text = "Valid: {{name}}, Invalid: {{broken, Incomplete: {missing}"
expected_variables = {"name"} # Only valid variables should be extracted
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
def test_parse_nested_braces(self):
"""Test handling of nested braces and complex syntax.
Reference: Issue #65 - Template Engine Foundation
"""
# Arrange
template_text = "Code: {{code.value}} and JSON: {\"key\": \"{{data.field}}\"}"
expected_variables = {"code.value", "data.field"}
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
class TestTemplateParserEdgeCases:
"""Test edge cases and error conditions for template parser."""
def setup_method(self):
"""Set up test environment."""
try:
from markitect.template.parser import TemplateParser
self.parser = TemplateParser()
except ImportError:
self.parser = None
def test_parse_extremely_long_template(self):
"""Test parsing performance with large templates.
Reference: Issue #65 - Performance Requirements
"""
# Arrange
# Create a large template with many variables
variables = [f"{{{{field_{i}}}}}" for i in range(1000)]
template_text = " ".join(variables)
expected_count = 1000
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
import time
start_time = time.time()
variables = self.parser.extract_variables(template_text)
parse_time = time.time() - start_time
assert len(variables) == expected_count
assert parse_time < 0.1 # Should parse large templates quickly
def test_parse_unicode_variables(self):
"""Test parsing templates with unicode content.
Reference: Issue #65 - Template Engine Foundation
"""
# Arrange
template_text = "Grüße {{name}}, café {{café.price}} €"
expected_variables = {"name", "café.price"}
# Act & Assert
if self.parser is None:
pytest.skip("TemplateParser not implemented yet - TDD RED phase")
variables = self.parser.extract_variables(template_text)
assert set(variables) == expected_variables
if __name__ == '__main__':
pytest.main([__file__, '-v'])