add pytests

This commit is contained in:
Jared Dillard
2025-05-16 01:17:29 -07:00
parent 19f42aa8cc
commit 012674a934
10 changed files with 297 additions and 4 deletions
+2
View File
@@ -40,6 +40,7 @@ dev = [
"mypy", "mypy",
"isort", "isort",
"pre-commit", "pre-commit",
"sphinx",
] ]
test = [ test = [
"pytest>=7.0.0", "pytest>=7.0.0",
@@ -84,4 +85,5 @@ filterwarnings = [
"error", "error",
"ignore::UserWarning", "ignore::UserWarning",
"ignore::DeprecationWarning", "ignore::DeprecationWarning",
"ignore::PendingDeprecationWarning",
] ]
+7 -4
View File
@@ -74,7 +74,9 @@ class LLMSFullManager:
if toctree: if toctree:
from docutils import nodes from docutils import nodes
for node in toctree.traverse(nodes.reference): # Use findall() instead of traverse() to avoid deprecation warning
# Convert generator to list for iteration
for node in list(toctree.findall(nodes.reference)):
if "refuri" in node.attributes: if "refuri" in node.attributes:
refuri = node.attributes["refuri"] refuri = node.attributes["refuri"]
if refuri and refuri.endswith(".html"): if refuri and refuri.endswith(".html"):
@@ -239,9 +241,10 @@ def doctree_resolved(app: Sphinx, doctree, docname: str):
from docutils import nodes from docutils import nodes
title = None title = None
for node in doctree.traverse(nodes.title): # findall() returns a generator, convert to list to check if it has elements
title = node.astext() title_nodes = list(doctree.findall(nodes.title))
break if title_nodes:
title = title_nodes[0].astext()
if title: if title:
_manager.update_page_title(docname, title) _manager.update_page_title(docname, title)
+49
View File
@@ -0,0 +1,49 @@
"""Pytest configuration for sphinx-llms-txt."""
import os
import shutil
import tempfile
from pathlib import Path
import pytest
# Use Path directly instead of sphinx_path to avoid deprecation warning
from sphinx.testing.util import SphinxTestApp
@pytest.fixture
def rootdir():
"""Get the root directory for test projects."""
return Path(os.path.dirname(__file__) or ".").absolute() / "roots"
@pytest.fixture
def temp_dir():
"""Create a temporary directory and delete it after the test."""
temp_path = Path(tempfile.mkdtemp())
yield temp_path
shutil.rmtree(temp_path, ignore_errors=True)
@pytest.fixture
def basic_sphinx_app(temp_dir, rootdir):
"""Create a basic Sphinx app for testing."""
src_dir = rootdir / "basic"
app = SphinxTestApp(
srcdir=src_dir,
builddir=temp_dir,
buildername="html",
freshenv=True,
)
yield app
# Custom cleanup to avoid missing_ok issue
import sys
from sphinx.testing.util import _clean_up_global_state
sys.path[:] = app._saved_path
_clean_up_global_state()
# Safe unlink that works with older Python versions
if hasattr(app, "docutils_conf_path") and app.docutils_conf_path.exists():
app.docutils_conf_path.unlink()
+22
View File
@@ -0,0 +1,22 @@
"""Configuration file for the basic Sphinx project."""
project = "Test Project"
copyright = "2025, Test"
author = "Test"
extensions = [
"sphinx_llms_txt",
]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
html_theme = "alabaster"
html_static_path = ["_static"]
# Configuration for sphinx-llms-txt
llms_txt_filename = "test-llms-full.txt"
llms_txt_verbose = True
# Master document
master_doc = "index"
+22
View File
@@ -0,0 +1,22 @@
"""Configuration file for the basic Sphinx project."""
project = "Test Project"
copyright = "2025, Test"
author = "Test"
extensions = [
"sphinx_llms_txt",
]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
html_theme = "alabaster"
html_static_path = ["_static"]
# Configuration for sphinx-llms-txt
llms_txt_filename = "custom-name.txt"
llms_txt_verbose = True
# Master document
master_doc = "index"
+16
View File
@@ -0,0 +1,16 @@
Welcome to Test Project's documentation!
=====================================
.. toctree::
:maxdepth: 2
:caption: Contents:
page1
page2
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
+14
View File
@@ -0,0 +1,14 @@
Page 1 Title
===========
This is the content of page 1.
Section 1
---------
Content for section 1.
Section 2
---------
Content for section 2.
+14
View File
@@ -0,0 +1,14 @@
Page 2 Title
===========
This is the content of page 2.
Section A
---------
Content for section A.
Section B
---------
Content for section B.
+69
View File
@@ -0,0 +1,69 @@
"""Integration tests for sphinx-llms-txt."""
from pathlib import Path
def test_build_html_with_llms_txt(basic_sphinx_app):
"""Test building HTML documentation with llms-txt enabled."""
app = basic_sphinx_app
app.build()
# Check if the output file was created
output_file = Path(app.outdir) / "test-llms-full.txt"
assert output_file.exists(), f"Output file {output_file} does not exist"
# Read the content of the output file
content = output_file.read_text()
# Check that content from all pages is included
assert "Welcome to Test Project's documentation!" in content
assert "Page 1 Title" in content
assert "Page 2 Title" in content
assert "Content for section 1" in content
assert "Content for section A" in content
def test_custom_filename(temp_dir, rootdir):
"""Test using a custom filename for the output."""
from sphinx.testing.util import SphinxTestApp
src_dir = rootdir / "basic"
# Create a copy of the configuration with a different filename
custom_conf = src_dir / "conf_custom.py"
with open(src_dir / "conf.py") as f:
conf_content = f.read()
conf_content = conf_content.replace(
'llms_txt_filename = "test-llms-full.txt"',
'llms_txt_filename = "custom-name.txt"',
)
with open(custom_conf, "w") as f:
f.write(conf_content)
# Create a new test app with the custom configuration
app = SphinxTestApp(
srcdir=src_dir,
builddir=temp_dir,
buildername="html",
freshenv=True,
confoverrides={"llms_txt_filename": "custom-name.txt"},
)
app.build()
# Check if the output file with the custom name was created
output_file = Path(app.outdir) / "custom-name.txt"
assert output_file.exists(), f"Output file {output_file} does not exist"
# Custom cleanup to avoid missing_ok issue
import sys
from sphinx.testing.util import _clean_up_global_state
sys.path[:] = app._saved_path
_clean_up_global_state()
# Safe unlink that works with older Python versions
if hasattr(app, "docutils_conf_path") and app.docutils_conf_path.exists():
app.docutils_conf_path.unlink()
+82
View File
@@ -0,0 +1,82 @@
"""Test the sphinx_llms_txt extension."""
from sphinx_llms_txt import LLMSFullManager, setup
def test_version():
"""Test that the version is defined."""
from sphinx_llms_txt import __version__
assert __version__
def test_setup_returns_valid_dict():
"""Test that the setup function returns a valid dict."""
# Mock a Sphinx app
class MockApp:
def __init__(self):
self.config_values = {}
self.connections = {}
def add_config_value(self, name, default, rebuild):
self.config_values[name] = (default, rebuild)
def connect(self, event, handler):
self.connections[event] = handler
app = MockApp()
result = setup(app)
# Check that result is a dict
assert isinstance(result, dict)
assert "version" in result
assert "parallel_read_safe" in result
assert "parallel_write_safe" in result
def test_llms_full_manager_initialization():
"""Test initialization of LLMSFullManager."""
manager = LLMSFullManager()
assert manager.page_titles == {}
assert manager.config == {}
assert manager.master_doc is None
assert manager.env is None
def test_manager_page_title_update():
"""Test updating page titles."""
manager = LLMSFullManager()
manager.update_page_title("doc1", "Title 1")
manager.update_page_title("doc2", "Title 2")
assert manager.page_titles["doc1"] == "Title 1"
assert manager.page_titles["doc2"] == "Title 2"
def test_set_config():
"""Test setting configuration."""
manager = LLMSFullManager()
config = {
"llms_txt_filename": "custom.txt",
"llms_txt_verbose": True,
}
manager.set_config(config)
assert manager.config == config
def test_set_master_doc():
"""Test setting master doc."""
manager = LLMSFullManager()
manager.set_master_doc("index")
assert manager.master_doc == "index"
def test_empty_page_order():
"""Test get_page_order returns empty list when env or master_doc not set."""
manager = LLMSFullManager()
assert manager.get_page_order() == []
# Set only master_doc, but not env
manager.set_master_doc("index")
assert manager.get_page_order() == []