Skip to content
Open
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@ When writing new tests:
- Use `pytest.mark.xfail(strict=True)` for known failures (strict=True means unexpected passes also fail)
- Hand-written per-issue regression tests go in `tests/nodenorm/by_issue/`
- GitHub-issue-driven tests are picked up automatically by `tests/github_issues/test_github_issues.py` via `GitHubIssuesTestCases`
- Import shared classes from `src.babel_validation.*` (e.g. `from src.babel_validation.services.nodenorm import CachedNodeNorm`)
- Import shared classes from `babel_validation.*` (e.g. `from babel_validation.services.nodenorm import CachedNodeNorm`)
31 changes: 21 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,48 @@ description = "A set of programs for validating the output of the Babel pipeline
license = "MIT"
readme = "README.md"
requires-python = ">=3.11"
# Runtime dependencies needed to USE the library (fetch GitHub-issue tests,
# parse them, and run them against NodeNorm/NameRes). PyGitHub is a core
# dependency because the test definitions live in GitHub issues, so every
# consumer needs it to obtain them.
dependencies = [
"black>=25.9.0",
"click>=8.1",
"pyyaml>=6.0",
"requests>=2.32.5",
"tqdm>=4.67.1",
Comment on lines 12 to 16
"filelock",
"deepdiff>=8.6.1",
"python-dotenv>=0.9.9",
"openapi-spec-validator>=0.7.2",
"pygithub>=2.8.1",
]

[project.urls]
Repository = "https://github.com/TranslatorSRI/babel-validation"

# Tooling for developing babel-validation itself (its pytest suite + formatter).
# A uv dependency-group is auto-installed by `uv run` / `uv sync` for local work
# and CI, but — unlike an extra — is NOT shipped to library consumers.
[dependency-groups]
dev = [
"black>=25.9.0",
"deepdiff>=8.6.1",
"openapi-spec-validator>=0.7.2",
"pytest>=9.0.2",
"pytest-timeout>=2.4.0",
"pytest-xdist[psutil]",
"pytest-subtests",
]

[project.urls]
Repository = "https://github.com/TranslatorSRI/babel-validation"

[project.scripts]
csv-to-babeltests = "src.babel_validation.tools.csv_to_babeltests:main"
csv-to-babeltests = "babel_validation.tools.csv_to_babeltests:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
# Package the entire `src/` directory so existing imports
# (`from src.babel_validation.X import Y`) continue to work after install.
packages = ["src"]
# src-layout: ship `src/babel_validation` as the top-level import package
# `babel_validation`, so consumers `import babel_validation` (not `src.…`).
packages = ["src/babel_validation"]

[tool.pytest.ini_options]
# Without testpaths, a bare `pytest` would also scan the website directories
Expand Down
Empty file removed src/__init__.py
Empty file.
4 changes: 2 additions & 2 deletions src/babel_validation/assertions/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- AUTO-GENERATED — do not edit by hand.
Regenerate with: uv run python -m src.babel_validation.assertions.gen_docs -->
Regenerate with: uv run python -m babel_validation.assertions.gen_docs -->

# BabelTest Assertion Types

Expand Down Expand Up @@ -240,4 +240,4 @@ babel_tests:

3. Import it in `__init__.py` and add an instance to `ASSERTION_HANDLERS`.

4. Run `uv run python -m src.babel_validation.assertions.gen_docs` to regenerate `README.md`.
4. Run `uv run python -m babel_validation.assertions.gen_docs` to regenerate `README.md`.
10 changes: 5 additions & 5 deletions src/babel_validation/assertions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
3. Set PARAMETERS, WIKI_EXAMPLES, and YAML_PARAMS class attributes for documentation.
4. Override test_param_set().
5. Import it here and add an instance to ASSERTION_HANDLERS.
6. Run `uv run python -m src.babel_validation.assertions.gen_docs` to regenerate README.md.
6. Run `uv run python -m babel_validation.assertions.gen_docs` to regenerate README.md.
"""

import re
from typing import Iterator

from src.babel_validation.core.testrow import TestResult, TestStatus
from babel_validation.core.testrow import TestResult, TestStatus


class AssertionHandler:
Expand Down Expand Up @@ -166,12 +166,12 @@ def test_param_set(self, params: list[str], nodenorm, nameres,


# Registry — import submodules after base classes are defined to avoid circular imports.
from src.babel_validation.assertions.nodenorm import ( # noqa: E402
from babel_validation.assertions.nodenorm import ( # noqa: E402
ResolvesHandler, DoesNotResolveHandler, ResolvesWithHandler,
ResolvesWithTypeHandler, DoesNotResolveWithHandler, HasLabelHandler,
)
from src.babel_validation.assertions.nameres import SearchByNameHandler # noqa: E402
from src.babel_validation.assertions.common import NeededHandler # noqa: E402
from babel_validation.assertions.nameres import SearchByNameHandler # noqa: E402
from babel_validation.assertions.common import NeededHandler # noqa: E402

ASSERTION_HANDLERS: dict[str, AssertionHandler] = {
h.NAME: h for h in [
Expand Down
2 changes: 1 addition & 1 deletion src/babel_validation/assertions/common.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from src.babel_validation.assertions import AssertionHandler
from babel_validation.assertions import AssertionHandler


class NeededHandler(AssertionHandler):
Expand Down
8 changes: 4 additions & 4 deletions src/babel_validation/assertions/gen_docs.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
"""Generate assertions/README.md from handler class attributes.

Run:
uv run python -m src.babel_validation.assertions.gen_docs
uv run python -m babel_validation.assertions.gen_docs
"""

from pathlib import Path

from src.babel_validation.assertions import (
from babel_validation.assertions import (
ASSERTION_HANDLERS, AssertionHandler, NodeNormTest, NameResTest,
)

README_PATH = Path(__file__).parent / "README.md"

INTRO = """\
<!-- AUTO-GENERATED — do not edit by hand.
Regenerate with: uv run python -m src.babel_validation.assertions.gen_docs -->
Regenerate with: uv run python -m babel_validation.assertions.gen_docs -->

# BabelTest Assertion Types

Expand Down Expand Up @@ -69,7 +69,7 @@

3. Import it in `__init__.py` and add an instance to `ASSERTION_HANDLERS`.

4. Run `uv run python -m src.babel_validation.assertions.gen_docs` to regenerate `README.md`.
4. Run `uv run python -m babel_validation.assertions.gen_docs` to regenerate `README.md`.
"""

_GROUP_HEADERS: dict[str, str] = {
Expand Down
8 changes: 4 additions & 4 deletions src/babel_validation/assertions/nameres.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import logging
from typing import Iterator

from src.babel_validation.assertions import NameResTest
from src.babel_validation.core.testrow import TestResult
from src.babel_validation.services.nameres import CachedNameRes
from src.babel_validation.services.nodenorm import CachedNodeNorm
from babel_validation.assertions import NameResTest
from babel_validation.core.testrow import TestResult
from babel_validation.services.nameres import CachedNameRes
from babel_validation.services.nodenorm import CachedNodeNorm


class SearchByNameHandler(NameResTest):
Expand Down
6 changes: 3 additions & 3 deletions src/babel_validation/assertions/nodenorm.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Iterator

from src.babel_validation.assertions import NodeNormTest
from src.babel_validation.core.testrow import TestResult
from src.babel_validation.services.nodenorm import CachedNodeNorm
from babel_validation.assertions import NodeNormTest
from babel_validation.core.testrow import TestResult
from babel_validation.services.nodenorm import CachedNodeNorm


class ResolvesHandler(NodeNormTest):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
from github import Github, Auth, Issue
from tqdm import tqdm

from src.babel_validation.assertions import ASSERTION_HANDLERS
from src.babel_validation.core.testrow import TestResult
from src.babel_validation.services.nameres import CachedNameRes
from src.babel_validation.services.nodenorm import CachedNodeNorm
from babel_validation.assertions import ASSERTION_HANDLERS
from babel_validation.core.testrow import TestResult
from babel_validation.services.nameres import CachedNameRes
from babel_validation.services.nodenorm import CachedNodeNorm

_logger = logging.getLogger(__name__)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from _pytest.mark import ParameterSet
from filelock import FileLock

from src.babel_validation.core.testrow import TestRow
from babel_validation.core.testrow import TestRow


class GoogleSheetTestCases:
Expand Down
6 changes: 3 additions & 3 deletions src/babel_validation/tools/csv_to_babeltests.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
import click
import yaml

from src.babel_validation.assertions import ASSERTION_HANDLERS
from src.babel_validation.core.testrow import TestStatus
from src.babel_validation.services.nodenorm import CachedNodeNorm
from babel_validation.assertions import ASSERTION_HANDLERS
from babel_validation.core.testrow import TestStatus
from babel_validation.services.nodenorm import CachedNodeNorm


# --- YAML emission ---------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion tests/github_issues/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from filelock import FileLock
from github import GithubException, Issue

from src.babel_validation.sources.github.github_issues_test_cases import GitHubIssuesTestCases
from babel_validation.sources.github.github_issues_test_cases import GitHubIssuesTestCases
from tests._pytest_helpers import deselected_by_markexpr

_github_token = None
Expand Down
8 changes: 4 additions & 4 deletions tests/github_issues/test_github_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

import pytest

from src.babel_validation.assertions import ASSERTION_HANDLERS
from src.babel_validation.services.nameres import CachedNameRes
from src.babel_validation.services.nodenorm import CachedNodeNorm
from src.babel_validation.core.testrow import TestResult, TestStatus
from babel_validation.assertions import ASSERTION_HANDLERS
from babel_validation.services.nameres import CachedNameRes
from babel_validation.services.nodenorm import CachedNodeNorm
from babel_validation.core.testrow import TestResult, TestStatus


def test_github_issue(request, target_info, github_issue_id, github_issue, github_issues_test_cases, subtests):
Expand Down
4 changes: 2 additions & 2 deletions tests/github_issues/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import pytest
import yaml

from src.babel_validation.core.testrow import TestStatus
from src.babel_validation.sources.github.github_issues_test_cases import GitHubIssuesTestCases
from babel_validation.core.testrow import TestStatus
from babel_validation.sources.github.github_issues_test_cases import GitHubIssuesTestCases

pytestmark = pytest.mark.unit

Expand Down
2 changes: 1 addition & 1 deletion tests/nameres/test_blocklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import requests
import pytest

from src.babel_validation.sources.google_sheets.blocklist import load_blocklist_from_gsheet
from babel_validation.sources.google_sheets.blocklist import load_blocklist_from_gsheet
from tests._pytest_helpers import deselected_by_markexpr

# The blocklist Google Sheet is downloaded lazily in pytest_generate_tests so
Expand Down
2 changes: 1 addition & 1 deletion tests/nameres/test_nameres_from_gsheet.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import urllib.parse
import requests
import pytest
from src.babel_validation.sources.google_sheets.google_sheet_test_cases import GoogleSheetTestCases
from babel_validation.sources.google_sheets.google_sheet_test_cases import GoogleSheetTestCases
from tests._pytest_helpers import deselected_by_markexpr

# Configuration options
Expand Down
2 changes: 1 addition & 1 deletion tests/nodenorm/test_nodenorm_from_gsheet.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import urllib.parse
import requests
import pytest
from src.babel_validation.sources.google_sheets.google_sheet_test_cases import GoogleSheetTestCases
from babel_validation.sources.google_sheets.google_sheet_test_cases import GoogleSheetTestCases
from tests._pytest_helpers import deselected_by_markexpr

# The Google Sheet is downloaded lazily in pytest_generate_tests so that runs
Expand Down
4 changes: 2 additions & 2 deletions tests/test_environment/test_assertions_docs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from src.babel_validation.assertions.gen_docs import generate_readme, README_PATH
from babel_validation.assertions.gen_docs import generate_readme, README_PATH


@pytest.mark.unit
Expand All @@ -10,5 +10,5 @@ def test_assertions_readme_is_up_to_date():
assert actual == expected, (
"assertions/README.md is out of date.\n"
"Regenerate it with:\n"
" uv run python -m src.babel_validation.assertions.gen_docs"
" uv run python -m babel_validation.assertions.gen_docs"
)
2 changes: 1 addition & 1 deletion tests/test_environment/test_env.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Test whether the test environment is functional.
import json

from src.babel_validation.sources.google_sheets.google_sheet_test_cases import GoogleSheetTestCases
from babel_validation.sources.google_sheets.google_sheet_test_cases import GoogleSheetTestCases


def test_google_sheet_has_test_cases():
Expand Down
4 changes: 2 additions & 2 deletions tests/tools/test_csv_to_babeltests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import pytest
import yaml

from src.babel_validation.tools.csv_to_babeltests import (
from babel_validation.tools.csv_to_babeltests import (
BlockEntry,
build_blocks,
emit_yaml,
Expand Down Expand Up @@ -213,7 +213,7 @@ def test_emit_yaml_single_element_param_sets_emit_as_bare_strings():

def test_emitted_assertion_names_match_handler_registry():
"""The names build_blocks emits must each resolve in ASSERTION_HANDLERS."""
from src.babel_validation.assertions import ASSERTION_HANDLERS
from babel_validation.assertions import ASSERTION_HANDLERS
blocks, _ = build_blocks(
ROWS,
curie_column="OutputID", label_column="Label",
Expand Down
36 changes: 22 additions & 14 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading