267 lines
7.1 KiB
Python
267 lines
7.1 KiB
Python
"""Tests for endpoint detectors."""
|
|
|
|
import pytest
|
|
import tempfile
|
|
import os
|
|
from pathlib import Path
|
|
from docgen.models import HTTPMethod
|
|
|
|
|
|
class TestPythonDetector:
|
|
"""Tests for PythonDetector."""
|
|
|
|
def test_fastapi_detection(self):
|
|
"""Test FastAPI endpoint detection."""
|
|
code = '''
|
|
from fastapi import FastAPI, APIRouter
|
|
app = FastAPI()
|
|
|
|
@app.get("/users")
|
|
async def get_users():
|
|
return {"users": []}
|
|
|
|
@app.post("/users")
|
|
async def create_user():
|
|
return {"id": 1}
|
|
|
|
router = APIRouter()
|
|
@router.get("/items")
|
|
async def get_items():
|
|
return {"items": []}
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import PythonDetector
|
|
detector = PythonDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 3
|
|
methods = [e.method for e in endpoints]
|
|
assert HTTPMethod.GET in methods
|
|
assert HTTPMethod.POST in methods
|
|
|
|
def test_flask_detection(self):
|
|
"""Test Flask endpoint detection."""
|
|
code = '''
|
|
from flask import Flask, Blueprint
|
|
|
|
app = Flask(__name__)
|
|
blueprint = Blueprint("api", __name__)
|
|
|
|
@blueprint.route("/items")
|
|
def get_items():
|
|
return {"items": []}
|
|
|
|
@blueprint.route("/items", methods=["POST"])
|
|
def create_item():
|
|
return {"id": 1}
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import PythonDetector
|
|
detector = PythonDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 2
|
|
|
|
def test_django_detection(self):
|
|
"""Test Django URL pattern detection."""
|
|
code = '''
|
|
from django.urls import path
|
|
from . import views
|
|
|
|
urlpatterns = [
|
|
path("users/", views.UserListView.as_view()),
|
|
path("users/<int:pk>/", views.UserDetailView.as_view()),
|
|
]
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import PythonDetector
|
|
detector = PythonDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) == 2
|
|
assert endpoints[0].path == "users/"
|
|
assert endpoints[1].path == "users/<int:pk>/"
|
|
|
|
|
|
class TestJavaScriptDetector:
|
|
"""Tests for JavaScriptDetector."""
|
|
|
|
def test_express_detection(self):
|
|
"""Test Express endpoint detection."""
|
|
code = '''
|
|
const express = require("express");
|
|
const router = express.Router();
|
|
|
|
router.get("/users", (req, res) => {
|
|
res.json({ users: [] });
|
|
});
|
|
|
|
router.post("/users", (req, res) => {
|
|
res.json({ id: 1 });
|
|
});
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.js', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import JavaScriptDetector
|
|
detector = JavaScriptDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 2
|
|
|
|
def test_fastify_detection(self):
|
|
"""Test Fastify endpoint detection."""
|
|
code = '''
|
|
const fastify = require("fastify")();
|
|
|
|
fastify.get("/items", async (request, reply) => {
|
|
return { items: [] };
|
|
});
|
|
|
|
fastify.post("/items", async (request, reply) => {
|
|
return { id: 1 };
|
|
});
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.js', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import JavaScriptDetector
|
|
detector = JavaScriptDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 2
|
|
|
|
|
|
class TestGoDetector:
|
|
"""Tests for GoDetector."""
|
|
|
|
def test_gin_detection(self):
|
|
"""Test Gin endpoint detection."""
|
|
code = '''
|
|
package main
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func main() {
|
|
r := gin.Default()
|
|
r.GET("/users", func(c *gin.Context) {
|
|
c.JSON(200, gin.H{"users": []})
|
|
})
|
|
r.POST("/users", func(c *gin.Context) {
|
|
c.JSON(201, gin.H{"id": 1})
|
|
})
|
|
}
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.go', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import GoDetector
|
|
detector = GoDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 2
|
|
|
|
def test_chi_detection(self):
|
|
"""Test chi endpoint detection."""
|
|
code = '''
|
|
package main
|
|
|
|
import (
|
|
"github.com/go-chi/chi"
|
|
)
|
|
|
|
func main() {
|
|
r := chi.NewRouter()
|
|
r.GET("/items", func(w http.ResponseWriter, r *http.Request) {
|
|
w.Write([]byte(`{"items": []}`))
|
|
})
|
|
r.POST("/items", func(w http.ResponseWriter, r *http.Request) {
|
|
w.Write([]byte(`{"id": 1}`))
|
|
})
|
|
}
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.go', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import GoDetector
|
|
detector = GoDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 2
|
|
|
|
|
|
class TestRustDetector:
|
|
"""Tests for RustDetector."""
|
|
|
|
def test_actix_detection(self):
|
|
"""Test Actix-web endpoint detection."""
|
|
code = '''
|
|
use actix_web::{web, App, HttpResponse};
|
|
|
|
#[get("/users")]
|
|
async fn list_users() -> HttpResponse {
|
|
HttpResponse::Ok().json(vec![])
|
|
}
|
|
|
|
#[post("/users")]
|
|
async fn create_user() -> HttpResponse {
|
|
HttpResponse::Created().json(serde_json::json!({"id": 1}))
|
|
}
|
|
'''
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.rs', delete=False) as f:
|
|
f.write(code)
|
|
f.flush()
|
|
|
|
from docgen.detectors import RustDetector
|
|
detector = RustDetector()
|
|
endpoints = detector.detect_endpoints(Path(f.name))
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(endpoints) >= 0
|
|
|
|
|
|
class TestBaseDetector:
|
|
"""Tests for BaseDetector functionality."""
|
|
|
|
def test_can_detect(self):
|
|
"""Test file extension detection."""
|
|
from docgen.detectors import PythonDetector, JavaScriptDetector
|
|
|
|
py_detector = PythonDetector()
|
|
js_detector = JavaScriptDetector()
|
|
|
|
assert py_detector.can_detect(Path("test.py")) is True
|
|
assert py_detector.can_detect(Path("test.js")) is False
|
|
assert js_detector.can_detect(Path("test.ts")) is True
|
|
assert js_detector.can_detect(Path("test.py")) is False
|