feat: add --json
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
"""Tests for JSON output functionality."""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from paperlib.models import PaperMetadata, SourceType
|
||||
from paperlib.utils import JSONOutputMixin
|
||||
|
||||
|
||||
class TestJSONOutputMixin:
|
||||
"""Test JSONOutputMixin utility functions."""
|
||||
|
||||
def test_format_metadata_for_json(self):
|
||||
"""Test formatting PaperMetadata for JSON output."""
|
||||
metadata = PaperMetadata(
|
||||
paper_id="test-paper-1",
|
||||
source_type=SourceType.ARXIV,
|
||||
source_id="2212.06340",
|
||||
title="Test Paper",
|
||||
authors=["Alice Smith", "Bob Jones"],
|
||||
categories=["cs.AI"],
|
||||
)
|
||||
|
||||
result = JSONOutputMixin.format_metadata_for_json(metadata)
|
||||
|
||||
assert result["paper_id"] == "test-paper-1"
|
||||
assert result["source_type"] == "arxiv"
|
||||
assert result["source_id"] == "2212.06340"
|
||||
assert result["title"] == "Test Paper"
|
||||
assert result["authors"] == ["Alice Smith", "Bob Jones"]
|
||||
assert result["categories"] == ["cs.AI"]
|
||||
|
||||
def test_format_metadata_for_json_dict(self):
|
||||
"""Test formatting dict metadata for JSON output."""
|
||||
metadata_dict = {
|
||||
"paper_id": "test-paper-1",
|
||||
"title": "Test Paper",
|
||||
"source_type": "local",
|
||||
}
|
||||
|
||||
result = JSONOutputMixin.format_metadata_for_json(metadata_dict)
|
||||
assert result == metadata_dict
|
||||
|
||||
def test_format_papers_list_for_json(self):
|
||||
"""Test formatting a list of papers for JSON output."""
|
||||
papers = [
|
||||
PaperMetadata(
|
||||
paper_id="paper-1",
|
||||
source_type=SourceType.LOCAL,
|
||||
title="Paper 1",
|
||||
),
|
||||
PaperMetadata(
|
||||
paper_id="paper-2",
|
||||
source_type=SourceType.ARXIV,
|
||||
title="Paper 2",
|
||||
),
|
||||
]
|
||||
|
||||
result = JSONOutputMixin.format_papers_list_for_json(papers)
|
||||
|
||||
assert "papers" in result
|
||||
assert "total" in result
|
||||
assert result["total"] == 2
|
||||
assert len(result["papers"]) == 2
|
||||
assert result["papers"][0]["paper_id"] == "paper-1"
|
||||
assert result["papers"][1]["paper_id"] == "paper-2"
|
||||
|
||||
|
||||
class TestCLIJSONOutput:
|
||||
"""Test CLI commands with JSON output."""
|
||||
|
||||
def run_paperlib_cmd(self, *args):
|
||||
"""Helper to run paperlib commands and parse JSON output."""
|
||||
cmd = ["uv", "run", "paperlib"] + list(args)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, cwd=Path.cwd())
|
||||
|
||||
if "--json" in args:
|
||||
try:
|
||||
output_data = json.loads(result.stdout)
|
||||
return result.returncode, output_data, result.stderr
|
||||
except json.JSONDecodeError as e:
|
||||
pytest.fail(f"Invalid JSON output: {e}\nOutput: {result.stdout}")
|
||||
|
||||
return result.returncode, result.stdout, result.stderr
|
||||
|
||||
def test_status_json_output(self):
|
||||
"""Test status command with JSON output."""
|
||||
# Create temporary library
|
||||
temp_lib = Path("./.tmp") / f"test_status_json_{hash(self)}"
|
||||
temp_lib.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
# Initialize library
|
||||
self.run_paperlib_cmd("init", str(temp_lib))
|
||||
|
||||
# Test status with JSON
|
||||
returncode, output_data, stderr = self.run_paperlib_cmd(
|
||||
"status", "--library", str(temp_lib), "--json"
|
||||
)
|
||||
|
||||
assert returncode == 0
|
||||
assert isinstance(output_data, dict)
|
||||
assert output_data["success"] is True
|
||||
assert "timestamp" in output_data
|
||||
assert "library_root" in output_data
|
||||
assert "config_path" in output_data
|
||||
assert "database_path" in output_data
|
||||
assert str(temp_lib.resolve()) in output_data["library_root"]
|
||||
|
||||
finally:
|
||||
if temp_lib.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(temp_lib)
|
||||
|
||||
def test_list_json_output_empty(self):
|
||||
"""Test list command with JSON output for empty library."""
|
||||
temp_lib = Path("./.tmp") / f"test_list_json_{hash(self)}"
|
||||
temp_lib.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
# Initialize library
|
||||
self.run_paperlib_cmd("init", str(temp_lib))
|
||||
|
||||
# Test list with JSON
|
||||
returncode, output_data, stderr = self.run_paperlib_cmd(
|
||||
"list", "--library", str(temp_lib), "--json"
|
||||
)
|
||||
|
||||
assert returncode == 0
|
||||
assert isinstance(output_data, dict)
|
||||
assert output_data["success"] is True
|
||||
assert output_data["papers"] == []
|
||||
assert output_data["total"] == 0
|
||||
|
||||
finally:
|
||||
if temp_lib.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(temp_lib)
|
||||
|
||||
def test_import_json_output(self):
|
||||
"""Test import command with JSON output."""
|
||||
temp_lib = Path("./.tmp") / f"test_import_json_{hash(self)}"
|
||||
temp_lib.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create sample PDF
|
||||
sample_pdf = Path("./.tmp") / f"test_import_json_{hash(self)}.pdf"
|
||||
with sample_pdf.open("wb") as f:
|
||||
f.write(b"%PDF-1.4\n%%EOF\n")
|
||||
|
||||
try:
|
||||
# Initialize library
|
||||
self.run_paperlib_cmd("init", str(temp_lib))
|
||||
|
||||
# Test import with JSON
|
||||
returncode, output_data, stderr = self.run_paperlib_cmd(
|
||||
"import",
|
||||
"--pdf",
|
||||
str(sample_pdf),
|
||||
"--title",
|
||||
"Test JSON Import",
|
||||
"--library",
|
||||
str(temp_lib),
|
||||
"--json",
|
||||
)
|
||||
|
||||
assert returncode == 0
|
||||
assert isinstance(output_data, dict)
|
||||
assert output_data["success"] is True
|
||||
assert "paper_id" in output_data
|
||||
assert output_data["title"] == "Test JSON Import"
|
||||
assert output_data["source_type"] == "local"
|
||||
assert "Successfully imported local PDF" in output_data["message"]
|
||||
assert "paper" in output_data
|
||||
assert isinstance(output_data["paper"], dict)
|
||||
|
||||
finally:
|
||||
if temp_lib.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(temp_lib)
|
||||
if sample_pdf.exists():
|
||||
sample_pdf.unlink()
|
||||
|
||||
def test_show_json_output(self):
|
||||
"""Test show command with JSON output."""
|
||||
temp_lib = Path("./.tmp") / f"test_show_json_{hash(self)}"
|
||||
temp_lib.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create sample PDF
|
||||
sample_pdf = Path("./.tmp") / f"test_show_json_{hash(self)}.pdf"
|
||||
with sample_pdf.open("wb") as f:
|
||||
f.write(b"%PDF-1.4\n%%EOF\n")
|
||||
|
||||
try:
|
||||
# Initialize and import
|
||||
self.run_paperlib_cmd("init", str(temp_lib))
|
||||
import_returncode, import_data, _ = self.run_paperlib_cmd(
|
||||
"import",
|
||||
"--pdf",
|
||||
str(sample_pdf),
|
||||
"--title",
|
||||
"Test JSON Show",
|
||||
"--library",
|
||||
str(temp_lib),
|
||||
"--json",
|
||||
)
|
||||
|
||||
assert import_returncode == 0
|
||||
paper_id = import_data["paper_id"]
|
||||
|
||||
# Test show with JSON
|
||||
returncode, output_data, stderr = self.run_paperlib_cmd(
|
||||
"show", paper_id, "--library", str(temp_lib), "--json"
|
||||
)
|
||||
|
||||
assert returncode == 0
|
||||
assert isinstance(output_data, dict)
|
||||
assert output_data["success"] is True
|
||||
assert "paper" in output_data
|
||||
assert output_data["paper"]["paper_id"] == paper_id
|
||||
assert output_data["paper"]["title"] == "Test JSON Show"
|
||||
assert "files_status" in output_data["paper"]
|
||||
assert "pdf_exists" in output_data["paper"]["files_status"]
|
||||
|
||||
finally:
|
||||
if temp_lib.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(temp_lib)
|
||||
if sample_pdf.exists():
|
||||
sample_pdf.unlink()
|
||||
|
||||
def test_show_json_not_found(self):
|
||||
"""Test show command with JSON output for non-existent paper."""
|
||||
temp_lib = Path("./.tmp") / f"test_show_json_nf_{hash(self)}"
|
||||
temp_lib.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
# Initialize library
|
||||
self.run_paperlib_cmd("init", str(temp_lib))
|
||||
|
||||
# Test show non-existent paper
|
||||
returncode, output_data, stderr = self.run_paperlib_cmd(
|
||||
"show", "nonexistent", "--library", str(temp_lib), "--json"
|
||||
)
|
||||
|
||||
assert returncode == 1
|
||||
assert isinstance(output_data, dict)
|
||||
assert output_data["success"] is False
|
||||
assert "error" in output_data
|
||||
assert "Paper not found" in output_data["error"]
|
||||
|
||||
finally:
|
||||
if temp_lib.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(temp_lib)
|
||||
|
||||
def test_convert_json_output(self):
|
||||
"""Test convert command with JSON output."""
|
||||
temp_lib = Path("./.tmp") / f"test_convert_json_{hash(self)}"
|
||||
temp_lib.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
# Initialize library
|
||||
self.run_paperlib_cmd("init", str(temp_lib))
|
||||
|
||||
# Test convert with no papers (JSON)
|
||||
returncode, output_data, stderr = self.run_paperlib_cmd(
|
||||
"convert", "--library", str(temp_lib), "--json"
|
||||
)
|
||||
|
||||
assert returncode == 0
|
||||
assert isinstance(output_data, dict)
|
||||
assert output_data["success"] is True
|
||||
assert output_data["action"] == "convert_pending"
|
||||
assert output_data["success_count"] == 0
|
||||
assert output_data["failure_count"] == 0
|
||||
assert output_data["total_attempted"] == 0
|
||||
|
||||
finally:
|
||||
if temp_lib.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(temp_lib)
|
||||
Reference in New Issue
Block a user