Files
local-api-docs-search/tests/test_indexers.py
7000pctAUTO 6cfac02dd6
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / build (push) Has been cancelled
Add test files (indexers, search, CLI, integration)
2026-02-03 02:41:14 +00:00

341 lines
8.4 KiB
Python

"""Tests for the indexers."""
import pytest
from src.indexer.openapi import OpenAPIIndexer
from src.indexer.readme import READMEIndexer
from src.indexer.code import CodeIndexer
from src.models.document import SourceType
class TestOpenAPIIndexer:
"""Tests for the OpenAPI indexer."""
@pytest.fixture
def sample_openapi_yaml(self):
"""Create a sample OpenAPI spec for testing."""
content = """
openapi: "3.0.0"
info:
title: Test API
version: "1.0.0"
description: A test API for unit testing
paths:
/users:
get:
summary: List users
description: Get a list of all users
operationId: listUsers
tags:
- users
parameters:
- name: limit
in: query
schema:
type: integer
description: Maximum number of users
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
type: object
post:
summary: Create user
operationId: createUser
tags:
- users
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
email:
type: string
responses:
'201':
description: User created
/users/{userId}:
get:
summary: Get user
operationId: getUser
parameters:
- name: userId
in: path
required: true
schema:
type: integer
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
required:
- id
- name
"""
return content
def test_index_openapi_yaml(self, tmp_path, sample_openapi_yaml):
"""Test indexing a YAML OpenAPI spec."""
file_path = tmp_path / "openapi.yaml"
file_path.write_text(sample_openapi_yaml)
indexer = OpenAPIIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) > 0
assert all(doc.source_type == SourceType.OPENAPI for doc in documents)
titles = [doc.title for doc in documents]
assert any("Test API" in title for title in titles)
assert any("GET" in title or "/users" in title for title in titles)
def test_index_openapi_json(self, tmp_path):
"""Test indexing a JSON OpenAPI spec."""
content = """{
"openapi": "3.0.0",
"info": {
"title": "JSON API",
"version": "1.0.0"
},
"paths": {}
}"""
file_path = tmp_path / "openapi.json"
file_path.write_text(content)
indexer = OpenAPIIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) > 0
def test_unsupported_file(self, tmp_path):
"""Test that unsupported files are ignored."""
file_path = tmp_path / "test.txt"
file_path.write_text("This is not an OpenAPI spec")
indexer = OpenAPIIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) == 0
class TestREADMEIndexer:
"""Tests for the README indexer."""
@pytest.fixture
def sample_readme(self):
"""Create a sample README for testing."""
content = """# Project Documentation
This is a sample project for testing the README indexer.
## Installation
To install the project, run:
```bash
pip install myproject
```
## Usage
The main function can be called as follows:
```python
from myproject import main
main()
```
## Configuration
You can configure the project using environment variables:
- `API_KEY`: Your API key
- `DEBUG`: Enable debug mode
## API Reference
### Endpoints
- `GET /users` - List all users
- `POST /users` - Create a new user
"""
return content
def test_index_readme(self, tmp_path, sample_readme):
"""Test indexing a README file."""
file_path = tmp_path / "README.md"
file_path.write_text(sample_readme)
indexer = READMEIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) > 0
assert all(doc.source_type == SourceType.README for doc in documents)
titles = [doc.title for doc in documents]
assert any("Project Documentation" in title for title in titles)
def test_section_extraction(self, tmp_path, sample_readme):
"""Test that sections are properly extracted."""
file_path = tmp_path / "README.md"
file_path.write_text(sample_readme)
indexer = READMEIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) >= 1
content = documents[0].content
assert "Installation" in content
assert "Usage" in content
def test_unsupported_extension(self, tmp_path):
"""Test that unsupported extensions are ignored."""
file_path = tmp_path / "readme.xyz"
file_path.write_text("# Readme")
indexer = READMEIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) == 0
class TestCodeIndexer:
"""Tests for the code indexer."""
@pytest.fixture
def sample_python(self):
"""Create a sample Python file for testing."""
content = '''"""Sample module for testing."""
def add_numbers(a, b):
"""Add two numbers together.
Args:
a: First number
b: Second number
Returns:
The sum of a and b
"""
return a + b
class Calculator:
"""A simple calculator class.
This class provides basic arithmetic operations.
"""
def __init__(self, initial_value=0):
"""Initialize the calculator.
Args:
initial_value: Starting value
"""
self.value = initial_value
def add(self, number):
"""Add a number to the current value.
Args:
number: Number to add
"""
self.value += number
'''
return content
def test_index_python(self, tmp_path, sample_python):
"""Test indexing a Python file."""
file_path = tmp_path / "sample.py"
file_path.write_text(sample_python)
indexer = CodeIndexer()
documents = indexer.index(tmp_path, recursive=False)
assert len(documents) > 0
assert all(doc.source_type == SourceType.CODE for doc in documents)
titles = [doc.title for doc in documents]
assert any("add_numbers" in title for title in titles)
assert any("Calculator" in title for title in titles)
def test_function_docstring(self, tmp_path, sample_python):
"""Test that function docstrings are extracted."""
file_path = tmp_path / "sample.py"
file_path.write_text(sample_python)
indexer = CodeIndexer()
documents = indexer.index(tmp_path, recursive=False)
add_doc = [d for d in documents if "add_numbers" in d.title]
if add_doc:
assert "Add two numbers" in add_doc[0].content
def test_class_docstring(self, tmp_path, sample_python):
"""Test that class docstrings are extracted."""
file_path = tmp_path / "sample.py"
file_path.write_text(sample_python)
indexer = CodeIndexer()
documents = indexer.index(tmp_path, recursive=False)
calc_doc = [d for d in documents if "Calculator" in d.title]
if calc_doc:
assert "simple calculator" in calc_doc[0].content.lower()
def test_jsdoc_extraction(self, tmp_path):
"""Test JSDoc comment extraction."""
content = '''
/**
* Multiplies two numbers.
* @param {number} a - First number
* @param {number} b - Second number
* @returns {number} The product of a and b
*/
function multiply(a, b) {
return a * b;
}
/**
* A Greeter class.
* @class
*/
class Greeter {
/**
* Create a greeter.
* @param {string} name - Name to greet
*/
constructor(name) {
this.name = name;
}
}
'''
file_path = tmp_path / "sample.js"
file_path.write_text(content)
indexer = CodeIndexer()
documents = indexer.index(tmp_path, recursive=False)
func_doc = [d for d in documents if "multiply" in d.title]
if func_doc:
assert "Multiplies two numbers" in func_doc[0].content
assert "number" in func_doc[0].content