343 lines
8.4 KiB
Python
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
|