Files
markitect-main/tests/test_schema_visualization.py
tegwick 1358ca17ec
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
refactor: Remove circular test dependencies and meta-testing anti-patterns
Clean up test infrastructure by removing problematic tests that create
circular dependencies and execute the test suite from within tests.

Key removals:
- Delete test_issue_57_test_efficiency_improvements.py entirely (12 tests)
  - Contained tests that ran `make test-tdd`, `make test-status` etc.
  - Created circular dependencies where tests execute the entire test suite
  - Violated separation of concerns between testing and test infrastructure

- Remove self-execution blocks from 11 test files
  - Eliminated `if __name__ == '__main__': pytest.main([__file__, '-v'])` patterns
  - Prevents confusion and potential circular execution paths
  - Test files should be run via pytest, not as standalone scripts

Test Infrastructure Improvements:
- Reduced test count from 701 to 689 tests (removed 12 problematic tests)
- Eliminated subprocess calls to `make test-*` commands from within tests
- Removed `pytest.main()` calls that could cause circular execution
- Maintained clean separation between test infrastructure and actual tests

Impact:
- No more tests testing tests (circular dependency elimination)
- Cleaner test execution without subprocess complexity
- Proper test isolation and independence
- Faster and more reliable test runs

The proper way to test infrastructure is to test the underlying functions
directly, not to execute the entire test suite from within a test.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-01 21:05:36 +02:00

428 lines
16 KiB
Python

"""
Tests for schema visualization output formatting and consistency.
These tests ensure the visualization scripts produce consistent, well-formatted
output in both emoji and ASCII modes, pinning down the exact style and format.
"""
import sys
import subprocess
import tempfile
from pathlib import Path
from textwrap import dedent
import pytest
# Add the project root to the path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))
from markitect.schema_generator import SchemaGenerator
class TestSchemaVisualization:
"""Test schema visualization output formatting."""
@pytest.fixture
def sample_markdown_file(self):
"""Create a sample markdown file for testing."""
content = dedent("""
# Main Title
This is the introduction paragraph.
## Section One
Content for section one.
### Subsection A
- Item 1
- Item 2
### Subsection B
More content here.
```python
def example():
return "code block"
```
## Section Two
Final section content.
""").strip()
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
f.write(content)
return Path(f.name)
def test_visualize_schema_emoji_mode_output_format(self, sample_markdown_file):
"""Test that emoji mode produces expected output format."""
try:
result = subprocess.run([
sys.executable, 'visualize_schema.py', str(sample_markdown_file)
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
# Check document header
assert "📋 DOCUMENT STRUCTURE:" in output
assert sample_markdown_file.name in output
# Check main sections are present
assert "📊 OVERVIEW" in output
assert "📑 HEADING STRUCTURE" in output
assert "📝 CONTENT STRUCTURE" in output
assert "🔍 COMPLEXITY ANALYSIS" in output
assert "🗺️ DOCUMENT MAP" in output
# Check content formatting
assert "Total Elements:" in output
assert "Schema Properties:" in output
assert "├─ Level 1:" in output
assert "│─ Level 2:" in output
assert "│─ Level 3:" in output
# Check content elements with emoji icons
assert "📄 Paragraphs" in output
assert "📋 Lists" in output
assert "💻 Code Blocks" in output
# Check complexity rating with emoji
complexity_ratings = ["🟢 Simple", "🟡 Moderate", "🔴 Complex"]
assert any(rating in output for rating in complexity_ratings)
# Check document map uses '#' symbols (count matches actual headings)
assert "H1: #" in output # 1 level-1 heading = 1 hash
assert "H2: ##" in output # 2 level-2 headings = 2 hashes
# Level 3 should have 2 headings based on our sample
assert "H3: ##" in output # 2 level-3 headings = 2 hashes
finally:
sample_markdown_file.unlink()
def test_visualize_schema_ascii_mode_output_format(self, sample_markdown_file):
"""Test that ASCII mode produces expected output format."""
try:
result = subprocess.run([
sys.executable, 'visualize_schema.py', str(sample_markdown_file), '--ascii'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
# Check document header (ASCII version)
assert "[DOC] DOCUMENT STRUCTURE:" in output
assert sample_markdown_file.name in output
# Check main sections are present (ASCII version)
assert "OVERVIEW" in output
assert "HEADING STRUCTURE" in output
assert "CONTENT STRUCTURE" in output
assert "COMPLEXITY ANALYSIS" in output
assert "DOCUMENT MAP" in output
# Check content formatting (ASCII tree structure)
assert "Total Elements:" in output
assert "Schema Properties:" in output
assert "+- Level 1:" in output
assert "|- Level 2:" in output
assert "|- Level 3:" in output
# Check content elements with ASCII tags
assert "[P] Paragraphs" in output
assert "[L] Lists" in output
assert "[C] Code Blocks" in output
# Check complexity rating (no emoji)
complexity_ratings = ["Simple", "Moderate", "Complex"]
assert any(rating in output for rating in complexity_ratings)
# Ensure no emoji complexity indicators
assert "🟢" not in output
assert "🟡" not in output
assert "🔴" not in output
# Check document map uses '#' symbols (count matches actual headings)
assert "H1: #" in output # 1 level-1 heading = 1 hash
assert "H2: ##" in output # 2 level-2 headings = 2 hashes
# Level 3 should have 2 headings based on our sample
assert "H3: ##" in output # 2 level-3 headings = 2 hashes
# Ensure no Unicode characters are present
assert "📋" not in output
assert "📊" not in output
assert "📑" not in output
assert "📝" not in output
assert "🔍" not in output
assert "🗺️" not in output
assert "" not in output
assert "" not in output
finally:
sample_markdown_file.unlink()
def test_visualize_schema_depth_limitation(self, sample_markdown_file):
"""Test that depth limitation works correctly."""
try:
result = subprocess.run([
sys.executable, 'visualize_schema.py',
str(sample_markdown_file), '--max-depth', '2'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
# Should have Level 1 and Level 2 headings
assert "├─ Level 1:" in output
assert "│─ Level 2:" in output
# Should NOT have Level 3 headings due to depth limit
assert "│─ Level 3:" not in output
finally:
sample_markdown_file.unlink()
def test_schema_summary_emoji_mode_output_format(self, sample_markdown_file):
"""Test that schema summary emoji mode produces expected format."""
try:
result = subprocess.run([
sys.executable, 'schema_summary.py', str(sample_markdown_file)
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
lines = output.strip().split('\n')
# Should have exactly 4 lines
assert len(lines) == 4
# Check each line format
assert lines[0].startswith("📋 ")
assert sample_markdown_file.name in lines[0]
assert lines[1].startswith("🏗️ Structure:")
assert "H1:" in lines[1] and "H2:" in lines[1] and "H3:" in lines[1]
assert lines[2].startswith("📝 Content:")
assert "Paragraphs:" in lines[2]
assert "Lists:" in lines[2]
assert lines[3].startswith("📊 Total:")
assert "elements" in lines[3]
finally:
sample_markdown_file.unlink()
def test_schema_summary_ascii_mode_output_format(self, sample_markdown_file):
"""Test that schema summary ASCII mode produces expected format."""
try:
result = subprocess.run([
sys.executable, 'schema_summary.py', str(sample_markdown_file), '--ascii'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
lines = output.strip().split('\n')
# Should have exactly 4 lines
assert len(lines) == 4
# Check each line format (ASCII version)
assert lines[0].startswith("[DOC] ")
assert sample_markdown_file.name in lines[0]
assert lines[1].startswith("[STRUCTURE] Structure:")
assert "H1:" in lines[1] and "H2:" in lines[1] and "H3:" in lines[1]
assert " -> " in lines[1] # ASCII arrow instead of →
assert lines[2].startswith("[CONTENT] Content:")
assert "Paragraphs:" in lines[2]
assert "Lists:" in lines[2]
assert lines[3].startswith("[TOTAL] Total:")
assert "elements" in lines[3]
# Ensure no emoji characters
assert "📋" not in output
assert "🏗️" not in output
assert "📝" not in output
assert "📊" not in output
finally:
sample_markdown_file.unlink()
def test_document_map_uses_hash_symbols_consistently(self, sample_markdown_file):
"""Test that document map consistently uses '#' symbols in both modes."""
try:
# Test emoji mode
result_emoji = subprocess.run([
sys.executable, 'visualize_schema.py', str(sample_markdown_file)
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
# Test ASCII mode
result_ascii = subprocess.run([
sys.executable, 'visualize_schema.py', str(sample_markdown_file), '--ascii'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result_emoji.returncode == 0
assert result_ascii.returncode == 0
emoji_output = result_emoji.stdout
ascii_output = result_ascii.stdout
# Both should use '#' symbols in document map, not Unicode blocks
for output in [emoji_output, ascii_output]:
# Should have '#' symbols (actual count matches headings in sample)
assert "H1: #" in output
assert "H2: ##" in output # 2 level-2 headings
# Should NOT have Unicode block characters
assert "" not in output
finally:
sample_markdown_file.unlink()
def test_no_horizontal_lines_or_frames(self, sample_markdown_file):
"""Test that output doesn't contain horizontal lines or frames."""
try:
# Test both modes
for args in [[], ['--ascii']]:
result = subprocess.run([
sys.executable, 'visualize_schema.py', str(sample_markdown_file)
] + args, capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
# Should NOT contain frame characters
assert "" not in output
assert "" not in output
assert "" not in output
assert "" not in output
assert "" not in args or "" not in output # Only check if not in ASCII mode
# Should NOT contain horizontal separator lines
lines = output.split('\n')
separator_lines = [line for line in lines if line.strip() and all(c in '─-' for c in line.strip())]
assert len(separator_lines) == 0, f"Found separator lines: {separator_lines}"
finally:
sample_markdown_file.unlink()
def test_visualization_handles_empty_file(self):
"""Test visualization with empty markdown file."""
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
f.write("")
empty_file = Path(f.name)
try:
result = subprocess.run([
sys.executable, 'visualize_schema.py', str(empty_file)
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
# Should handle empty file gracefully
assert result.returncode == 0
output = result.stdout
# Should still show basic structure
assert "DOCUMENT STRUCTURE:" in output
assert "OVERVIEW" in output
finally:
empty_file.unlink()
def test_visualization_error_handling(self):
"""Test error handling for non-existent files."""
result = subprocess.run([
sys.executable, 'visualize_schema.py', 'nonexistent_file.md'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 1
assert "File not found" in result.stdout
def test_help_output_format(self):
"""Test help output contains expected information."""
result = subprocess.run([
sys.executable, 'visualize_schema.py', '--help'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
assert "Visualize markdown document schema structure" in output
assert "--max-depth" in output
assert "--ascii" in output
assert "Use ASCII characters only" in output
class TestOutputConsistency:
"""Test output consistency and formatting standards."""
def test_ascii_mode_contains_no_unicode(self):
"""Ensure ASCII mode output contains no Unicode characters."""
content = "# Test\n\nSome content with **bold** text.\n\n## Section\n\n- Item 1\n- Item 2"
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
f.write(content)
test_file = Path(f.name)
try:
result = subprocess.run([
sys.executable, 'visualize_schema.py', str(test_file), '--ascii'
], capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
# Check that all characters are ASCII (code points < 128)
for char in output:
assert ord(char) < 128, f"Non-ASCII character found: {char} (ord: {ord(char)})"
finally:
test_file.unlink()
def test_section_header_formatting_consistency(self):
"""Test that section headers are consistently formatted."""
content = "# Title\n\nContent here.\n\n## Section\n\nMore content."
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
f.write(content)
test_file = Path(f.name)
try:
for mode_args in [[], ['--ascii']]:
result = subprocess.run([
sys.executable, 'visualize_schema.py', str(test_file)
] + mode_args, capture_output=True, text=True, cwd=Path(__file__).parent.parent)
assert result.returncode == 0
output = result.stdout
lines = output.split('\n')
# Find section headers
section_headers = []
for line in lines:
line = line.strip()
if line and any(section in line for section in
['OVERVIEW', 'HEADING STRUCTURE', 'CONTENT STRUCTURE',
'COMPLEXITY ANALYSIS', 'DOCUMENT MAP']):
section_headers.append(line)
# All section headers should be in uppercase
for header in section_headers:
# Remove emoji/tags and check the text part
text_part = header.split()[-2:] # Get last two words like "HEADING STRUCTURE"
text = ' '.join(text_part)
if text.isupper():
assert True # Good
else:
# Allow for cases like "DOCUMENT MAP" where the emoji/tag is separate
main_text = ' '.join([word for word in header.split() if word.isupper() or word in ['STRUCTURE', 'ANALYSIS', 'MAP', 'OVERVIEW', 'CONTENT']])
assert main_text, f"Section header not properly formatted: {header}"
finally:
test_file.unlink()