Expand certification checks to support multiple programming languages including Python, JavaScript/TypeScript, Go, Rust, Ruby, Java, and C/C++. This includes: - Language detection based on file extensions. - Syntax validation using language-specific tools (e.g., ast for Python, tsc for TypeScript, cargo check for Rust). - Test suite detection and execution for various frameworks (e.g., go test, cargo test, npm test, pytest/unittest). - Ignore common build/dependency directories during scans. - Update tests to reflect generalized syntax checking. - Add new badge assets for certification levels.
154 lines
4.9 KiB
Python
154 lines
4.9 KiB
Python
"""Tests for WOMM certification checks."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from womm.certify import (
|
|
CertificationReport,
|
|
Level,
|
|
certify,
|
|
_check_has_source_files,
|
|
_check_project_exists,
|
|
_check_syntax,
|
|
_check_readme_exists,
|
|
_check_no_todo_comments,
|
|
)
|
|
|
|
|
|
@pytest.fixture()
|
|
def empty_project(tmp_path: Path) -> Path:
|
|
"""An empty project directory."""
|
|
return tmp_path
|
|
|
|
|
|
@pytest.fixture()
|
|
def bronze_project(tmp_path: Path) -> Path:
|
|
"""A project that should achieve Bronze certification."""
|
|
(tmp_path / "main.py").write_text("print('hello')\n")
|
|
return tmp_path
|
|
|
|
|
|
@pytest.fixture()
|
|
def silver_project(tmp_path: Path) -> Path:
|
|
"""A project that should achieve at least Silver."""
|
|
(tmp_path / "main.py").write_text("def add(a, b):\n return a + b\n")
|
|
tests_dir = tmp_path / "tests"
|
|
tests_dir.mkdir()
|
|
(tests_dir / "__init__.py").write_text("")
|
|
(tests_dir / "test_main.py").write_text(
|
|
"from pathlib import Path\nimport sys\n"
|
|
"sys.path.insert(0, str(Path(__file__).parent.parent))\n"
|
|
"from main import add\n\n"
|
|
"def test_add():\n assert add(1, 2) == 3\n"
|
|
)
|
|
return tmp_path
|
|
|
|
|
|
class TestLevel:
|
|
def test_level_ordering(self) -> None:
|
|
assert Level.BRONZE < Level.SILVER < Level.GOLD < Level.PLATINUM
|
|
|
|
def test_label(self) -> None:
|
|
assert Level.GOLD.label == "Gold"
|
|
assert Level.NONE.label == "Uncertified"
|
|
|
|
def test_colour_hex(self) -> None:
|
|
assert Level.GOLD.colour_hex == "#FFD700"
|
|
|
|
|
|
class TestIndividualChecks:
|
|
def test_project_exists_pass(self, tmp_path: Path) -> None:
|
|
result = _check_project_exists(tmp_path)
|
|
assert result.passed
|
|
|
|
def test_project_exists_fail(self, tmp_path: Path) -> None:
|
|
result = _check_project_exists(tmp_path / "nonexistent")
|
|
assert not result.passed
|
|
|
|
def test_has_source_files_pass(self, bronze_project: Path) -> None:
|
|
result = _check_has_source_files(bronze_project)
|
|
assert result.passed
|
|
|
|
def test_has_source_files_fail(self, empty_project: Path) -> None:
|
|
result = _check_has_source_files(empty_project)
|
|
assert not result.passed
|
|
|
|
def test_syntax_pass(self, bronze_project: Path) -> None:
|
|
result = _check_syntax(bronze_project)
|
|
assert result.passed
|
|
|
|
def test_syntax_fail(self, tmp_path: Path) -> None:
|
|
(tmp_path / "bad.py").write_text("def oops(\n")
|
|
result = _check_syntax(tmp_path)
|
|
assert not result.passed
|
|
|
|
def test_readme_exists_pass(self, tmp_path: Path) -> None:
|
|
(tmp_path / "README.md").write_text("# Hello\n")
|
|
result = _check_readme_exists(tmp_path)
|
|
assert result.passed
|
|
|
|
def test_readme_exists_fail(self, empty_project: Path) -> None:
|
|
result = _check_readme_exists(empty_project)
|
|
assert not result.passed
|
|
|
|
def test_no_todos_pass(self, bronze_project: Path) -> None:
|
|
result = _check_no_todo_comments(bronze_project)
|
|
assert result.passed
|
|
|
|
def test_no_todos_fail(self, tmp_path: Path) -> None:
|
|
(tmp_path / "main.py").write_text("# TODO: fix this\n")
|
|
result = _check_no_todo_comments(tmp_path)
|
|
assert not result.passed
|
|
|
|
|
|
class TestCertify:
|
|
def test_empty_project_gets_none(self, empty_project: Path) -> None:
|
|
report = certify(empty_project)
|
|
# Empty dir exists but has no source files
|
|
assert report.level == Level.NONE
|
|
|
|
def test_bronze_project(self, bronze_project: Path) -> None:
|
|
report = certify(bronze_project, target_level=Level.BRONZE)
|
|
assert report.level >= Level.BRONZE
|
|
|
|
def test_report_has_results(self, bronze_project: Path) -> None:
|
|
report = certify(bronze_project)
|
|
assert len(report.results) > 0
|
|
assert all(r.name and r.message for r in report.results)
|
|
|
|
def test_target_level_limits_checks(self, bronze_project: Path) -> None:
|
|
report = certify(bronze_project, target_level=Level.BRONZE)
|
|
levels_checked = {r.level for r in report.results}
|
|
assert Level.PLATINUM not in levels_checked
|
|
|
|
|
|
class TestCertificationReport:
|
|
def test_level_all_pass(self) -> None:
|
|
from womm.certify import CheckResult
|
|
|
|
report = CertificationReport(
|
|
project_path=Path("/tmp/test"),
|
|
project_name="test",
|
|
results=[
|
|
CheckResult("check1", True, "ok", Level.BRONZE),
|
|
CheckResult("check2", True, "ok", Level.SILVER),
|
|
],
|
|
)
|
|
assert report.level >= Level.SILVER
|
|
|
|
def test_level_with_failure(self) -> None:
|
|
from womm.certify import CheckResult
|
|
|
|
report = CertificationReport(
|
|
project_path=Path("/tmp/test"),
|
|
project_name="test",
|
|
results=[
|
|
CheckResult("check1", True, "ok", Level.BRONZE),
|
|
CheckResult("check2", False, "nope", Level.SILVER),
|
|
],
|
|
)
|
|
assert report.level == Level.BRONZE
|