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
- Update TODO.md to reflect completed issue-facade capability fixes - Archive old CLI structure files that were moved to capabilities/issue-facade - Reorganize remaining CLI components into issue_tracker/ package - Add test coverage for issue #166 substack theme implementation - Update document manager and markdown command plugins with latest improvements - Complete project reorganization following capability-based architecture This commit finalizes the issue-facade capability enhancement project and ensures the main repository reflects the current state of all completed work. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
183 lines
7.2 KiB
Python
183 lines
7.2 KiB
Python
"""
|
|
Tests for Issue #166: Document theme that mimics substack fonts and fontsizes
|
|
|
|
This module tests the implementation of a Substack-style document theme
|
|
for enhanced long-form reading experience.
|
|
"""
|
|
|
|
import pytest
|
|
import tempfile
|
|
import os
|
|
from pathlib import Path
|
|
from unittest.mock import patch, MagicMock
|
|
import json
|
|
|
|
# Add project root to path for imports
|
|
import sys
|
|
project_root = Path(__file__).parent.parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
|
|
class TestIssue166SubstackTheme:
|
|
"""Test Substack theme implementation for long-form reading."""
|
|
|
|
def setup_method(self):
|
|
"""Set up test environment."""
|
|
# Create temporary directory for test outputs
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.markdown_content = """# The Mythology of Ireland
|
|
|
|
This is a test document for validating the Substack theme implementation.
|
|
The theme should provide excellent readability for longer essays online.
|
|
|
|
## Typography and Layout
|
|
|
|
The Substack style emphasizes:
|
|
- Serif fonts for body text (Spectral)
|
|
- Sans-serif fonts for headings (Lora)
|
|
- Generous line spacing for readability
|
|
- Warm color palette with soft cream background
|
|
|
|
### Key Design Principles
|
|
|
|
1. **Readability First**: Typography optimized for long-form content
|
|
2. **Visual Breathing Room**: Generous margins and spacing
|
|
3. **Print-Inspired**: Traditional typographic principles
|
|
4. **Eye Comfort**: Soft, low-contrast color scheme
|
|
|
|
> "The best interfaces are almost invisible to the user. They don't get in the way of the content."
|
|
> — A design principle that guides Substack's approach
|
|
|
|
This longer paragraph demonstrates how the theme handles extended body text.
|
|
It should be comfortable to read with appropriate line height, font size,
|
|
and spacing that reduces eye strain during extended reading sessions.
|
|
"""
|
|
|
|
def teardown_method(self):
|
|
"""Clean up test environment."""
|
|
# Clean up temporary files
|
|
import shutil
|
|
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
|
|
|
def test_substack_theme_available_in_layered_themes(self):
|
|
"""Test that substack theme is available in LAYERED_THEMES - Issue #166."""
|
|
from markitect.plugins.builtin.markdown_commands import LAYERED_THEMES
|
|
|
|
# Substack theme should be available as a document theme
|
|
assert 'substack' in LAYERED_THEMES
|
|
substack_theme = LAYERED_THEMES['substack']
|
|
|
|
# Should be scoped as a document theme
|
|
assert substack_theme['scope'] == 'document'
|
|
|
|
# Should have required typography properties
|
|
properties = substack_theme['properties']
|
|
assert 'font_family' in properties
|
|
assert 'max_width' in properties
|
|
assert 'body_background' in properties
|
|
assert 'heading_font_family' in properties
|
|
|
|
def test_substack_theme_typography_properties(self):
|
|
"""Test that substack theme has correct typography properties - Issue #166."""
|
|
from markitect.plugins.builtin.markdown_commands import LAYERED_THEMES
|
|
|
|
substack_theme = LAYERED_THEMES['substack']
|
|
properties = substack_theme['properties']
|
|
|
|
# Should use serif font for body text (Spectral)
|
|
assert 'Spectral' in properties['font_family']
|
|
|
|
# Should use sans-serif for headings (Lora)
|
|
assert 'Lora' in properties['heading_font_family']
|
|
|
|
# Should have appropriate max width for readability
|
|
max_width = properties['max_width']
|
|
# Convert to int if it has px suffix
|
|
if max_width.endswith('px'):
|
|
width_value = int(max_width[:-2])
|
|
else:
|
|
width_value = int(max_width)
|
|
assert 600 <= width_value <= 750 # Good range for long-form reading
|
|
|
|
# Should have warm cream background
|
|
assert properties['body_background'] == '#FAF9F1'
|
|
|
|
def test_substack_theme_legacy_compatibility(self):
|
|
"""Test that substack theme works with legacy TEMPLATE_STYLES - Issue #166."""
|
|
from markitect.plugins.builtin.markdown_commands import TEMPLATE_STYLES
|
|
|
|
# Should be available in legacy template styles for backward compatibility
|
|
assert 'substack' in TEMPLATE_STYLES
|
|
substack_legacy = TEMPLATE_STYLES['substack']
|
|
|
|
# Should have required legacy properties
|
|
assert 'body_color' in substack_legacy
|
|
assert 'font_family' in substack_legacy
|
|
assert 'max_width' in substack_legacy
|
|
|
|
def test_substack_theme_cli_integration(self):
|
|
"""Test Substack theme through CLI md-render command - Issue #166."""
|
|
input_file = Path(self.temp_dir) / "substack_test.md"
|
|
input_file.write_text(self.markdown_content)
|
|
|
|
output_file = Path(self.temp_dir) / "substack_test.html"
|
|
|
|
from markitect.cli import cli
|
|
from click.testing import CliRunner
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, [
|
|
'md-render',
|
|
str(input_file),
|
|
'--output', str(output_file),
|
|
'--theme', 'substack'
|
|
])
|
|
|
|
assert result.exit_code == 0, f"CLI command failed: {result.output}"
|
|
assert output_file.exists()
|
|
|
|
html_content = output_file.read_text()
|
|
|
|
# Should contain Substack-specific styling
|
|
assert 'Spectral' in html_content # Body font
|
|
assert 'Lora' in html_content # Heading font
|
|
assert '#FAF9F1' in html_content # Background color
|
|
|
|
def test_substack_theme_html_generation(self):
|
|
"""Test HTML generation with Substack theme - Issue #166."""
|
|
from markitect.plugins.builtin.markdown_commands import generate_html_with_embedded_markdown
|
|
|
|
test_markdown = "# Test Article\n\nThis is a test paragraph for the Substack theme."
|
|
title = "Substack Theme Test"
|
|
|
|
html = generate_html_with_embedded_markdown(
|
|
test_markdown, title, "substack", "", {}
|
|
)
|
|
|
|
# Should generate valid HTML
|
|
assert '<!DOCTYPE html>' in html
|
|
assert title in html
|
|
|
|
# Should include Substack styling
|
|
assert 'Spectral' in html # Body font should be present
|
|
assert 'Lora' in html # Heading font should be present
|
|
assert '#FAF9F1' in html # Background color should be present
|
|
|
|
def test_substack_theme_layered_combination(self):
|
|
"""Test Substack theme combines properly with other layer themes - Issue #166."""
|
|
from markitect.plugins.builtin.markdown_commands import parse_theme_string, combine_theme_properties
|
|
|
|
# Test combining substack document theme with light mode and standard UI
|
|
theme_list = parse_theme_string("light,standard,substack")
|
|
|
|
assert 'light' in theme_list # Mode theme
|
|
assert 'standard' in theme_list # UI theme
|
|
assert 'substack' in theme_list # Document theme
|
|
|
|
# Should be able to apply layered themes
|
|
combined_styles = combine_theme_properties(theme_list)
|
|
|
|
# Should include properties from all themes
|
|
assert 'body_background' in combined_styles # From light theme
|
|
assert 'editor_panel_bg' in combined_styles # From standard UI theme
|
|
assert 'font_family' in combined_styles # From substack document theme |