diff --git a/pyproject.toml b/pyproject.toml index 324d022..6f7eada 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,7 @@ addopts = [ ] pythonpath = [".", "src", "tests"] testpaths = ["tests"] +norecursedirs = ["tests/fixtures"] markers = [ "flaky: tests that can randomly fail through no change to the code", "slow: marks tests as slow (deselect with '-m \"not slow\"')", diff --git a/tests/fixtures/test_project/README.md b/tests/fixtures/test_project/README.md new file mode 100644 index 0000000..ff62544 --- /dev/null +++ b/tests/fixtures/test_project/README.md @@ -0,0 +1,73 @@ +# mypackage + +Minimal test project for manual validation of `reqstool-python-hatch-plugin`. + +## Prerequisites + +A `.venv` must exist inside this directory with the plugin, Hatch, pytest, and reqstool installed. +If it is missing, recreate it from `tests/fixtures/test_project/`: + +```bash +python3.13 -m venv .venv +.venv/bin/pip install -e ../../../ # install plugin in editable mode +.venv/bin/pip install hatch pytest reqstool +``` + +## Validation + +Run all commands from `tests/fixtures/test_project/`. + +### 1 — Run tests + +```bash +.venv/bin/pytest tests/ --junit-xml=build/test-results/junit.xml -v +``` + +Expected: `test_hello` passes. + +### 2 — Build + +```bash +HATCH_ENV_TYPE_VIRTUAL_PATH=.venv .venv/bin/hatch build +``` + +Expected output (sdist phase): +1. `[reqstool] plugin loaded` +2. `[reqstool] added reqstool_config.yml to dist/mypackage-0.1.0.tar.gz` + +### 3 — Check artefacts + +```bash +# annotations.yml must exist locally +test -f build/reqstool/annotations.yml && echo "OK: annotations.yml" + +# reqstool_config.yml must NOT be in project root (injected directly into tarball) +test ! -f reqstool_config.yml && echo "OK: no loose reqstool_config.yml" + +# sdist must contain reqstool_config.yml and dataset files +tar -tzf dist/mypackage-0.1.0.tar.gz | sort +``` + +Expected entries in the sdist: +- `mypackage-0.1.0/reqstool_config.yml` +- `mypackage-0.1.0/docs/reqstool/requirements.yml` +- `mypackage-0.1.0/docs/reqstool/software_verification_cases.yml` + +Note: unlike the poetry plugin, hatch injects `reqstool_config.yml` directly into the tarball +and does not bundle `annotations.yml` — those are generated locally in `build/reqstool/`. + +### 4 — Run reqstool status + +Extract the sdist and merge in the local build outputs, then run `reqstool status`: + +```bash +mkdir -p /tmp/mypackage-reqstool +tar -xzf dist/mypackage-0.1.0.tar.gz -C /tmp/mypackage-reqstool +mkdir -p /tmp/mypackage-reqstool/mypackage-0.1.0/build/reqstool +mkdir -p /tmp/mypackage-reqstool/mypackage-0.1.0/build/test-results +cp build/reqstool/annotations.yml /tmp/mypackage-reqstool/mypackage-0.1.0/build/reqstool/ +cp build/test-results/junit.xml /tmp/mypackage-reqstool/mypackage-0.1.0/build/test-results/ +.venv/bin/reqstool status local -p /tmp/mypackage-reqstool/mypackage-0.1.0 +``` + +Expected: all green — `REQ_001` implemented, `T1 P1`, no missing tests or SVCs. diff --git a/tests/fixtures/test_project/docs/reqstool/requirements.yml b/tests/fixtures/test_project/docs/reqstool/requirements.yml new file mode 100644 index 0000000..5eb6310 --- /dev/null +++ b/tests/fixtures/test_project/docs/reqstool/requirements.yml @@ -0,0 +1,15 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/reqstool/reqstool-client/main/src/reqstool/resources/schemas/v1/requirements.schema.json + +metadata: + urn: mypackage + variant: microservice + title: Mypackage Requirements + url: https://github.com/reqstool/reqstool-python-hatch-plugin + +requirements: + - id: REQ_001 + title: Hello function + significance: shall + description: The hello function shall return "hello". + categories: ["functional-suitability"] + revision: "0.1.0" diff --git a/tests/fixtures/test_project/docs/reqstool/software_verification_cases.yml b/tests/fixtures/test_project/docs/reqstool/software_verification_cases.yml new file mode 100644 index 0000000..da083ba --- /dev/null +++ b/tests/fixtures/test_project/docs/reqstool/software_verification_cases.yml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/reqstool/reqstool-client/main/src/reqstool/resources/schemas/v1/software_verification_cases.schema.json + +cases: + - id: SVC_001 + requirement_ids: ["REQ_001"] + title: "Hello function returns hello" + verification: automated-test + revision: "0.1.0" diff --git a/tests/fixtures/test_project/pyproject.toml b/tests/fixtures/test_project/pyproject.toml new file mode 100644 index 0000000..5847f6d --- /dev/null +++ b/tests/fixtures/test_project/pyproject.toml @@ -0,0 +1,25 @@ +[build-system] +build-backend = "hatchling.build" +requires = ["hatchling"] + +[project] +name = "mypackage" +version = "0.1.0" +description = "Minimal test project for reqstool-python-hatch-plugin" +requires-python = ">=3.13" + +[tool.hatch.build.targets.sdist] +include = ["src", "docs/reqstool"] + +[tool.pytest.ini_options] +addopts = ["--import-mode=importlib"] +pythonpath = ["src"] +testpaths = ["tests"] +junit_family = "xunit2" + +[tool.hatch.build.hooks.reqstool] +dependencies = ["reqstool-python-hatch-plugin"] +sources = ["src", "tests"] +test_results = ["build/**/junit.xml"] +dataset_directory = "docs/reqstool" +output_directory = "build/reqstool" diff --git a/tests/fixtures/test_project/src/mypackage/__init__.py b/tests/fixtures/test_project/src/mypackage/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/test_project/src/mypackage/main.py b/tests/fixtures/test_project/src/mypackage/main.py new file mode 100644 index 0000000..09b2484 --- /dev/null +++ b/tests/fixtures/test_project/src/mypackage/main.py @@ -0,0 +1,6 @@ +from reqstool_python_decorators.decorators.decorators import Requirements + + +@Requirements("REQ_001") +def hello(): + return "hello" diff --git a/tests/fixtures/test_project/tests/test_main.py b/tests/fixtures/test_project/tests/test_main.py new file mode 100644 index 0000000..72e7562 --- /dev/null +++ b/tests/fixtures/test_project/tests/test_main.py @@ -0,0 +1,8 @@ +from reqstool_python_decorators.decorators.decorators import SVCs + +from mypackage.main import hello + + +@SVCs("SVC_001") +def test_hello(): + assert hello() == "hello"