Files
local-api-docs-search/tests/test_indexers.py
7000pctAUTO 8fadb35db5
Some checks failed
CI / build (push) Has been cancelled
CI / test (push) Has been cancelled
Add test files
2026-02-03 01:25:54 +00:00

343 lines
8.4 KiB
Python

"""Tests for the indexers."""
import tempfile
from pathlib import Path
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