Box of handy tools for Sphinx providing comprehensive extensions and enhancements for documentation generation.
Comprehensive testing framework for Sphinx extensions providing HTML/LaTeX regression testing, fixtures, development tools, and testing infrastructure. These utilities enable developers to create robust tests for Sphinx extensions and ensure consistent documentation output.
Core testing infrastructure for creating and managing Sphinx application instances for testing.
class SphinxBuilder:
"""Builder for testing Sphinx extensions."""
def __init__(self, **kwargs) -> None: ...
def build(self, filenames: List[str]) -> None:
"""Build specified files."""
def get_output(self, filename: str) -> str:
"""Get built output content for a file."""
def get_warnings(self) -> List[str]:
"""Get build warnings."""
def make_test_app(**kwargs) -> Sphinx:
"""
Create Sphinx application for testing.
Args:
**kwargs: Configuration options for test app
Returns:
Configured Sphinx application instance
"""
def run_setup(app: Sphinx) -> None:
"""
Run extension setup for testing.
Args:
app: Sphinx application instance
"""Utilities for testing HTML output with regression detection and comparison.
class HTMLRegressionFixture:
"""HTML regression testing utilities."""
def __init__(self, test_dir: str) -> None:
"""
Initialize HTML regression fixture.
Args:
test_dir: Directory containing test files
"""
def check_output(self, filename: str, expected_file: str) -> None:
"""Check HTML output against expected results."""
def update_expected(self, filename: str) -> None:
"""Update expected output file with current results."""
def check_html_regression(test_output: str, expected_output: str) -> None:
"""
Check HTML output against expected results.
Args:
test_output: Generated HTML output
expected_output: Expected HTML output
Raises:
AssertionError: If outputs don't match
"""
def normalize_html(html_content: str) -> str:
"""
Normalize HTML content for comparison.
Args:
html_content: Raw HTML content
Returns:
Normalized HTML content
"""
def remove_html_footer(html_content: str) -> str:
"""
Remove Sphinx-generated footer from HTML content.
Args:
html_content: HTML content with footer
Returns:
HTML content without footer
"""Specialized testing utilities for LaTeX output validation and regression detection.
class LaTeXRegressionFixture:
"""LaTeX regression testing utilities."""
def __init__(self, test_dir: str) -> None:
"""
Initialize LaTeX regression fixture.
Args:
test_dir: Directory containing test files
"""
def check_output(self, filename: str, expected_file: str) -> None:
"""Check LaTeX output against expected results."""
def normalize_latex(self, latex_content: str) -> str:
"""Normalize LaTeX content for comparison."""
def check_latex_regression(test_output: str, expected_output: str) -> None:
"""
Check LaTeX output against expected results.
Args:
test_output: Generated LaTeX output
expected_output: Expected LaTeX output
Raises:
AssertionError: If outputs don't match
"""
def normalize_latex_whitespace(latex_content: str) -> str:
"""
Normalize whitespace in LaTeX content.
Args:
latex_content: Raw LaTeX content
Returns:
LaTeX content with normalized whitespace
"""Utilities for testing asset copying and management in Sphinx extensions.
def check_asset_copy(app: Sphinx, asset_name: str, expected_location: str) -> None:
"""
Verify that assets are copied to the correct location.
Args:
app: Sphinx application instance
asset_name: Name of asset file
expected_location: Expected location in build output
Raises:
AssertionError: If asset is not found in expected location
"""
def verify_css_inclusion(html_output: str, css_file: str) -> None:
"""
Verify that CSS file is included in HTML output.
Args:
html_output: Generated HTML content
css_file: CSS filename to check for
Raises:
AssertionError: If CSS file is not included
"""
def check_js_inclusion(html_output: str, js_file: str) -> None:
"""
Verify that JavaScript file is included in HTML output.
Args:
html_output: Generated HTML content
js_file: JavaScript filename to check for
Raises:
AssertionError: If JavaScript file is not included
"""Testing utilities for Sphinx configuration validation and processing.
class ConfigTester:
"""Utilities for testing Sphinx configuration."""
def __init__(self, base_config: Dict[str, Any]) -> None:
"""
Initialize configuration tester.
Args:
base_config: Base configuration dictionary
"""
def test_config_value(self, key: str, value: Any, should_pass: bool = True) -> None:
"""Test configuration value validation."""
def test_missing_required(self, required_keys: List[str]) -> None:
"""Test behavior with missing required configuration."""
def test_config_validation(config: Dict[str, Any], validator_func: Callable) -> None:
"""
Test configuration validation function.
Args:
config: Configuration dictionary to test
validator_func: Validation function to test
Raises:
AssertionError: If validation behaves unexpectedly
"""Base classes and utilities for testing Sphinx extensions.
class SphinxTestCase:
"""Base class for Sphinx extension testing."""
def setup_app(self, **kwargs) -> Sphinx:
"""
Set up test Sphinx application.
Args:
**kwargs: Configuration options
Returns:
Configured Sphinx application
"""
def build_docs(self, builder: str = 'html') -> None:
"""
Build documentation for testing.
Args:
builder: Builder name to use
"""
def get_output(self, filename: str) -> str:
"""
Get built output content.
Args:
filename: Output filename to retrieve
Returns:
File content as string
"""
def assert_build_succeeds(self) -> None:
"""Assert that documentation build succeeds."""
def assert_no_warnings(self) -> None:
"""Assert that build produces no warnings."""
class ExtensionTestCase(SphinxTestCase):
"""Base class for testing individual extensions."""
extension_name: str = None
def test_setup(self) -> None:
"""Test extension setup process."""
def test_configuration(self) -> None:
"""Test extension configuration handling."""Specialized testing utilities for Sphinx directives and roles.
def test_directive(directive_class: Type[SphinxDirective], content: List[str],
options: Dict[str, Any] = {}) -> List[Node]:
"""
Test directive processing.
Args:
directive_class: Directive class to test
content: Directive content lines
options: Directive options
Returns:
Generated nodes from directive
"""
def test_role(role_func: Callable, text: str, options: Dict[str, Any] = {}) -> Tuple[List[Node], List[system_message]]:
"""
Test role processing.
Args:
role_func: Role function to test
text: Role text content
options: Role options
Returns:
Tuple of generated nodes and messages
"""
class DirectiveTestCase:
"""Test case for directive testing."""
def test_directive_parsing(self, directive_class: Type[SphinxDirective]) -> None:
"""Test directive argument and option parsing."""
def test_directive_output(self, directive_class: Type[SphinxDirective]) -> None:
"""Test directive node generation."""Utilities for creating mocks and fixtures for testing.
class MockApp:
"""Mock Sphinx application for lightweight testing."""
def __init__(self, config: Dict[str, Any] = {}) -> None: ...
def setup_extension(self, extension: str) -> None: ...
def add_config_value(self, name: str, default: Any, rebuild: str) -> None: ...
class MockBuilder:
"""Mock builder for testing build processes."""
def __init__(self, name: str = 'html') -> None: ...
def read_doc(self, docname: str) -> None: ...
def write_doc(self, docname: str, doctree: Element) -> None: ...
def create_test_source_dir(content_map: Dict[str, str]) -> str:
"""
Create temporary source directory with test content.
Args:
content_map: Mapping of filenames to content
Returns:
Path to created temporary directory
"""
def cleanup_test_dir(test_dir: str) -> None:
"""
Clean up temporary test directory.
Args:
test_dir: Directory path to clean up
"""Utilities for end-to-end integration testing of Sphinx extensions.
def run_integration_test(extension_name: str, test_docs_dir: str,
expected_outputs: Dict[str, str]) -> None:
"""
Run full integration test for extension.
Args:
extension_name: Name of extension to test
test_docs_dir: Directory containing test documentation
expected_outputs: Expected output files and their content
Raises:
AssertionError: If integration test fails
"""
class IntegrationTestSuite:
"""Test suite for integration testing."""
def __init__(self, extensions: List[str]) -> None: ...
def add_test_case(self, name: str, source_files: Dict[str, str]) -> None: ...
def run_all_tests(self) -> None: ...
def compare_build_outputs(output_dir1: str, output_dir2: str,
ignore_patterns: List[str] = []) -> bool:
"""
Compare two build output directories.
Args:
output_dir1: First output directory
output_dir2: Second output directory
ignore_patterns: File patterns to ignore in comparison
Returns:
True if directories match, False otherwise
"""Utilities for performance testing and benchmarking Sphinx extensions.
def benchmark_build_time(app: Sphinx, iterations: int = 5) -> float:
"""
Benchmark documentation build time.
Args:
app: Sphinx application to benchmark
iterations: Number of iterations to run
Returns:
Average build time in seconds
"""
def profile_extension_setup(extension_name: str) -> Dict[str, float]:
"""
Profile extension setup performance.
Args:
extension_name: Extension to profile
Returns:
Dictionary of timing information
"""
class PerformanceTestCase:
"""Test case for performance testing."""
def test_build_performance(self, max_time: float) -> None:
"""Test that build completes within specified time."""
def test_memory_usage(self, max_memory: int) -> None:
"""Test maximum memory usage during build."""Utilities for testing error handling and edge cases.
def test_error_handling(func: Callable, error_cases: List[Tuple[Any, Type[Exception]]]) -> None:
"""
Test function error handling.
Args:
func: Function to test
error_cases: List of (input, expected_exception) tuples
"""
def assert_warning_raised(warning_class: Type[Warning], func: Callable, *args, **kwargs) -> None:
"""
Assert that specific warning is raised.
Args:
warning_class: Warning class to expect
func: Function that should raise warning
*args: Function arguments
**kwargs: Function keyword arguments
"""
class ErrorTestCase:
"""Test case for error handling testing."""
def test_missing_dependencies(self) -> None:
"""Test behavior with missing dependencies."""
def test_invalid_configuration(self) -> None:
"""Test handling of invalid configuration."""
def test_malformed_input(self) -> None:
"""Test handling of malformed input."""Install with Tessl CLI
npx tessl i tessl/pypi-sphinx-toolbox