Source code for wads.tests.test_scripts

"""Unit tests for CI scripts."""

import json
import os
from pathlib import Path
from unittest.mock import patch
import pytest


[docs] class TestReadCiConfig: """Test read_ci_config.py script."""
[docs] def test_reads_config_successfully(self, tmp_path): """Test that config is read correctly.""" from wads.scripts.read_ci_config import read_and_export_ci_config # Create test pyproject.toml pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" version = "0.1.0" [tool.wads.ci.testing] python_versions = ["3.10", "3.12"] coverage_enabled = true """ ) # Mock GitHub Actions environment output_file = tmp_path / 'output.txt' env_file = tmp_path / 'env.txt' summary_file = tmp_path / 'summary.txt' with patch.dict( 'os.environ', { 'GITHUB_OUTPUT': str(output_file), 'GITHUB_ENV': str(env_file), 'GITHUB_STEP_SUMMARY': str(summary_file), }, ): result = read_and_export_ci_config(tmp_path) assert result == 0 # Check outputs output_content = output_file.read_text() assert 'project-name=test-project' in output_content assert '3.10' in output_content # Check env vars env_content = env_file.read_text() assert 'PROJECT_NAME=test-project' in env_content
[docs] def test_handles_missing_pyproject(self, tmp_path): """Test error handling for missing pyproject.toml.""" from wads.scripts.read_ci_config import read_and_export_ci_config result = read_and_export_ci_config(tmp_path / "nonexistent") assert result == 1
[docs] def test_works_without_github_env(self, tmp_path): """Test graceful degradation without GitHub environment.""" from wads.scripts.read_ci_config import read_and_export_ci_config pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" """ ) # Should not crash without GITHUB_OUTPUT with patch.dict('os.environ', {}, clear=True): result = read_and_export_ci_config(tmp_path) # Should succeed but outputs won't be written assert result == 0
[docs] class TestValidateCiEnv: """Test validate_ci_env.py script."""
[docs] def test_validates_required_vars_present(self, tmp_path): """Test validation passes when required vars are present.""" from wads.scripts.validate_ci_env import validate_ci_environment pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" [tool.wads.ci.env] required_envvars = ["API_KEY"] """ ) with patch.dict('os.environ', {'API_KEY': 'secret'}): success, missing = validate_ci_environment(tmp_path) assert success assert len(missing) == 0
[docs] def test_detects_missing_required_vars(self, tmp_path): """Test validation fails when required vars are missing.""" from wads.scripts.validate_ci_env import validate_ci_environment pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" [tool.wads.ci.env] required_envvars = ["MISSING_VAR", "ANOTHER_MISSING"] """ ) with patch.dict('os.environ', {}, clear=True): success, missing = validate_ci_environment(tmp_path) assert not success assert "MISSING_VAR" in missing assert "ANOTHER_MISSING" in missing
[docs] def test_handles_no_required_vars(self, tmp_path): """Test validation passes when no vars are required.""" from wads.scripts.validate_ci_env import validate_ci_environment pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" """ ) success, missing = validate_ci_environment(tmp_path) assert success assert len(missing) == 0
[docs] class TestSetEnvVars: """Test set_env_vars.py script."""
[docs] def test_sets_vars_from_secrets_context(self, tmp_path): """Test setting environment variables from secrets context.""" from wads.scripts.set_env_vars import set_environment_variables pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" [tool.wads.ci.env] required_envvars = ["DATABASE_URL"] test_envvars = ["TEST_SECRET"] extra_envvars = ["OPTIONAL_VAR"] """ ) env_file = tmp_path / 'env.txt' summary_file = tmp_path / 'summary.txt' secrets = { "DATABASE_URL": "postgres://localhost/db", "TEST_SECRET": "test123", "OPTIONAL_VAR": "optional_value", } with patch.dict( 'os.environ', { 'GITHUB_ENV': str(env_file), 'GITHUB_STEP_SUMMARY': str(summary_file), 'SECRETS_CONTEXT': json.dumps(secrets), }, ): result = set_environment_variables(tmp_path) assert result == 0 env_content = env_file.read_text() assert 'DATABASE_URL' in env_content assert 'postgres://localhost/db' in env_content
[docs] def test_fails_on_missing_required_var(self, tmp_path): """Test failure when required var is missing.""" from wads.scripts.set_env_vars import set_environment_variables pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" [tool.wads.ci.env] required_envvars = ["CRITICAL_VAR"] """ ) env_file = tmp_path / 'env.txt' with patch.dict( 'os.environ', {'GITHUB_ENV': str(env_file), 'SECRETS_CONTEXT': '{}'} ): result = set_environment_variables(tmp_path) assert result == 1
[docs] def test_skips_reserved_vars(self, tmp_path): """Test that reserved variables are not set.""" from wads.scripts.set_env_vars import set_environment_variables pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [project] name = "test-project" [tool.wads.ci.env] required_envvars = ["GITHUB_TOKEN", "MY_VAR"] """ ) env_file = tmp_path / 'env.txt' secrets = {"GITHUB_TOKEN": "should_not_be_set", "MY_VAR": "should_be_set"} with patch.dict( 'os.environ', {'GITHUB_ENV': str(env_file), 'SECRETS_CONTEXT': json.dumps(secrets)}, ): result = set_environment_variables(tmp_path) # Should fail because GITHUB_TOKEN is skipped but required assert result == 1
[docs] class TestBuildDist: """Test build_dist.py script."""
[docs] def test_build_minimal_package(self, tmp_path, monkeypatch): """Test building a minimal package.""" from wads.scripts.build_dist import build_distributions # Create minimal pyproject.toml pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "test-pkg" version = "0.1.0" """ ) # Create package directory pkg_dir = tmp_path / "test_pkg" pkg_dir.mkdir() (pkg_dir / "__init__.py").write_text('__version__ = "0.1.0"') monkeypatch.chdir(tmp_path) result = build_distributions( output_dir=str(tmp_path / "dist"), build_sdist=True, build_wheel=True ) assert result == 0 dist_dir = tmp_path / "dist" assert dist_dir.exists() # Check that at least one distribution was created files = list(dist_dir.iterdir()) assert len(files) > 0
[docs] def test_build_wheel_only(self, tmp_path, monkeypatch): """Test building only wheel.""" from wads.scripts.build_dist import build_distributions pyproject = tmp_path / "pyproject.toml" pyproject.write_text( """ [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "test-pkg" version = "0.1.0" """ ) pkg_dir = tmp_path / "test_pkg" pkg_dir.mkdir() (pkg_dir / "__init__.py").write_text("") monkeypatch.chdir(tmp_path) result = build_distributions( output_dir=str(tmp_path / "dist"), build_sdist=False, build_wheel=True ) assert result == 0 dist_dir = tmp_path / "dist" files = list(dist_dir.iterdir()) # Should have wheel assert any(f.suffix == '.whl' for f in files)
[docs] class TestInstallDeps: """Test install_deps.py script."""
[docs] def test_installs_pypi_packages(self): """Test installing packages from PyPI.""" from wads.scripts.install_deps import install_pypi_packages # Test with a simple package result = install_pypi_packages(['pip']) assert result is True
[docs] def test_handles_empty_package_list(self): """Test handling empty package list.""" from wads.scripts.install_deps import install_pypi_packages result = install_pypi_packages([]) assert result is True
[docs] def test_install_from_requirements_file(self, tmp_path): """Test installing from requirements.txt.""" from wads.scripts.install_deps import install_from_dependency_files # Create requirements file req_file = tmp_path / "requirements.txt" req_file.write_text("pip>=20.0\n") result = install_from_dependency_files([str(req_file)]) assert result is True
[docs] def test_handles_missing_file_gracefully(self, tmp_path): """Test handling missing dependency file.""" from wads.scripts.install_deps import install_from_dependency_files # Should handle missing file gracefully result = install_from_dependency_files([str(tmp_path / "nonexistent.txt")]) # Should still succeed (just skip the missing file) assert result is True
if __name__ == "__main__": pytest.main([__file__, "-v"])