Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Ruff lint
run: ruff check scripts/
- name: Ruff format check
run: ruff format --check scripts/
- name: Mypy
run: mypy scripts/ --ignore-missing-imports

test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Run tests
run: pytest --cov=scripts --cov-report=xml -v
- name: Upload coverage
if: matrix.python-version == '3.12'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
continue-on-error: true
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
hooks:
- id: mypy
additional_dependencies:
- types-PyYAML
- tomli>=2.0
55 changes: 55 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[project]
name = "mini-wiki"
version = "3.0.8"
description = "AI Agent skill package for automatic project documentation generation"
authors = [
{ name = "trsoliu" }
]
license = { text = "Apache-2.0" }
requires-python = ">=3.10"
dependencies = [
"PyYAML>=6.0",
"tomli>=2.0; python_version<'3.11'",
]

[project.optional-dependencies]
dev = [
"pytest>=8.0",
"pytest-cov>=5.0",
"mypy>=1.10",
"ruff>=0.5.0",
"types-PyYAML",
]

[tool.ruff]
target-version = "py310"
line-length = 120
src = ["scripts"]

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"F", # pyflakes
"W", # pycodestyle warnings
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"B", # flake8-bugbear
"A", # flake8-builtins
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"RUF", # ruff-specific rules
]

[tool.ruff.format]
quote-style = "double"

[tool.mypy]
python_version = "3.10"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = false

[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["scripts"]
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Mini-Wiki test suite."""
74 changes: 74 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Shared pytest fixtures for Mini-Wiki tests."""

import json
from pathlib import Path
from typing import Dict

import pytest


@pytest.fixture
def tmp_project(tmp_path: Path) -> Path:
"""Create a temporary project directory structure."""
# Create basic project structure
(tmp_path / "src").mkdir()
(tmp_path / "tests").mkdir()
(tmp_path / "docs").mkdir()

# Create some sample files
(tmp_path / "src" / "main.py").write_text("def main():\n pass\n")
(tmp_path / "src" / "utils.py").write_text("def helper():\n return True\n")
(tmp_path / "README.md").write_text("# Test Project\n")

return tmp_path


@pytest.fixture
def sample_markdown(tmp_path: Path) -> Path:
"""Create a sample markdown file for testing."""
content = """# Module Documentation

## Overview
This is a test module.

## API Reference

### Function: test_func

```python
def test_func(x: int) -> int:
return x * 2
```

## Examples

```python
result = test_func(5)
assert result == 10
```

## Architecture

```mermaid
flowchart TB
A[Input] --> B[Process]
B --> C[Output]
```
"""
md_file = tmp_path / "test.md"
md_file.write_text(content)
return md_file


@pytest.fixture
def sample_structure() -> Dict:
"""Sample project structure data."""
return {
"project_type": ["python", "nodejs"],
"modules": [
{"name": "core", "path": "src/core", "files": 5},
{"name": "utils", "path": "src/utils", "files": 3},
{"name": "api", "path": "src/api", "files": 8},
],
"tech_stack": ["python", "fastapi", "pytest"],
}
64 changes: 64 additions & 0 deletions tests/test_check_quality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""Tests for check_quality.py module."""

import sys
from pathlib import Path

import pytest

# Add scripts to path
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))

from check_quality import QualityMetrics, analyze_document


def test_analyze_document_basic(sample_markdown):
"""Test basic document analysis."""
metrics = analyze_document(str(sample_markdown))

assert metrics.file_path == str(sample_markdown)
assert metrics.line_count > 0
assert metrics.section_count >= 2 # At least 2 H2 sections
assert metrics.diagram_count >= 1 # At least 1 mermaid diagram
assert metrics.code_example_count >= 1 # At least 1 code example


def test_analyze_document_quality_levels(tmp_path):
"""Test quality level classification."""
# Basic quality document
basic_doc = tmp_path / "basic.md"
basic_doc.write_text("""# Title
## Section 1
Some content.
""")

metrics = analyze_document(str(basic_doc))
assert metrics.section_count < 8
assert metrics.quality_level in ["basic", "standard"]


def test_analyze_document_nonexistent():
"""Test handling of nonexistent file."""
metrics = analyze_document("/nonexistent/file.md")
assert len(metrics.issues) > 0
assert "无法读取文件" in metrics.issues[0]


def test_analyze_document_mermaid_detection(tmp_path):
"""Test mermaid diagram detection."""
doc = tmp_path / "with_diagram.md"
doc.write_text("""# Title

```mermaid
flowchart TB
A --> B
```

```mermaid
classDiagram
class Foo
```
""")

metrics = analyze_document(str(doc))
assert metrics.diagram_count == 2
assert metrics.class_diagram_count == 1
Loading
Loading