added tests

This commit is contained in:
Brian Bjarke Jensen
2025-09-19 19:38:10 +02:00
parent 0abd398c10
commit b426d43de0
16 changed files with 1919 additions and 0 deletions
@@ -0,0 +1,22 @@
name: Test CI Templates
on:
push:
branches: [main]
pull_request:
jobs:
code-quality:
name: Code Quality
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
python-version: "3.11"
working-directory: "."
test:
name: Run Tests
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
python-version: "3.11"
coverage-package: "test_package"
pytest-args: "--verbose"
+30
View File
@@ -0,0 +1,30 @@
# Test Package
A simple Python package for testing CI templates.
## Features
- Basic calculator operations
- Utility functions
- Comprehensive test suite
- Type hints
- Code quality tools integration
## Development
```bash
# Install dependencies
uv sync --all-extras
# Run tests
uv run pytest
# Run code quality checks
uv run mypy .
uv run ruff check .
uv run ruff format --check .
```
## Testing CI Templates
This project is used to test the CI templates in the parent repository.
+82
View File
@@ -0,0 +1,82 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "test-package"
version = "0.1.0"
description = "Test package for CI template validation"
authors = [
{ name = "Test Author", email = "[email protected]" }
]
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"requests>=2.28.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"mypy>=1.0.0",
"ruff>=0.1.0",
"pyupgrade>=3.0.0",
]
test = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"pytest-mock>=3.10.0",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--strict-markers",
"--strict-config",
"--verbose",
"--cov=test_package",
"--cov-report=term-missing",
]
[tool.mypy]
python_version = "3.10"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
[tool.ruff]
target-version = "py310"
line-length = 88
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
]
[tool.coverage.run]
source = ["test_package"]
omit = ["tests/*"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if settings.DEBUG",
"raise AssertionError",
"raise NotImplementedError",
"if 0:",
"if __name__ == .__main__.:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]
@@ -0,0 +1,8 @@
"""Test package for CI template validation."""
__version__ = "0.1.0"
from .calculator import Calculator
from .utils import format_number
__all__ = ["Calculator", "format_number"]
@@ -0,0 +1,31 @@
"""Calculator module for basic arithmetic operations."""
from typing import Union
Number = Union[int, float]
class Calculator:
"""A simple calculator class."""
def add(self, a: Number, b: Number) -> Number:
"""Add two numbers."""
return a + b
def subtract(self, a: Number, b: Number) -> Number:
"""Subtract b from a."""
return a - b
def multiply(self, a: Number, b: Number) -> Number:
"""Multiply two numbers."""
return a * b
def divide(self, a: Number, b: Number) -> float:
"""Divide a by b."""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
def power(self, base: Number, exponent: Number) -> Number:
"""Raise base to the power of exponent."""
return base ** exponent
@@ -0,0 +1,24 @@
"""Utility functions for the test package."""
from typing import Union
def format_number(number: Union[int, float], precision: int = 2) -> str:
"""Format a number with specified precision."""
if isinstance(number, int):
return str(number)
return f"{number:.{precision}f}"
def is_even(number: int) -> bool:
"""Check if a number is even."""
return number % 2 == 0
def factorial(n: int) -> int:
"""Calculate factorial of a number."""
if n < 0:
raise ValueError("Factorial is not defined for negative numbers")
if n == 0 or n == 1:
return 1
return n * factorial(n - 1)
@@ -0,0 +1,47 @@
"""Tests for the calculator module."""
import pytest
from test_package.calculator import Calculator
class TestCalculator:
"""Test cases for Calculator class."""
def setup_method(self):
"""Set up test fixtures."""
self.calc = Calculator()
def test_add(self):
"""Test addition operation."""
assert self.calc.add(2, 3) == 5
assert self.calc.add(-1, 1) == 0
assert self.calc.add(0.1, 0.2) == pytest.approx(0.3)
def test_subtract(self):
"""Test subtraction operation."""
assert self.calc.subtract(5, 3) == 2
assert self.calc.subtract(1, 1) == 0
assert self.calc.subtract(-1, -2) == 1
def test_multiply(self):
"""Test multiplication operation."""
assert self.calc.multiply(3, 4) == 12
assert self.calc.multiply(-2, 3) == -6
assert self.calc.multiply(0, 100) == 0
def test_divide(self):
"""Test division operation."""
assert self.calc.divide(10, 2) == 5.0
assert self.calc.divide(7, 2) == 3.5
assert self.calc.divide(-6, 3) == -2.0
def test_divide_by_zero(self):
"""Test division by zero raises error."""
with pytest.raises(ValueError, match="Cannot divide by zero"):
self.calc.divide(5, 0)
def test_power(self):
"""Test power operation."""
assert self.calc.power(2, 3) == 8
assert self.calc.power(5, 0) == 1
assert self.calc.power(2, -1) == 0.5
@@ -0,0 +1,41 @@
"""Tests for the utils module."""
import pytest
from test_package.utils import format_number, is_even, factorial
class TestUtils:
"""Test cases for utility functions."""
def test_format_number_integer(self):
"""Test formatting integers."""
assert format_number(42) == "42"
assert format_number(-5) == "-5"
def test_format_number_float(self):
"""Test formatting floats."""
assert format_number(3.14159) == "3.14"
assert format_number(3.14159, 3) == "3.142"
assert format_number(2.0) == "2.00"
def test_is_even(self):
"""Test even number detection."""
assert is_even(2) is True
assert is_even(4) is True
assert is_even(1) is False
assert is_even(3) is False
assert is_even(0) is True
assert is_even(-2) is True
assert is_even(-1) is False
def test_factorial_positive(self):
"""Test factorial of positive numbers."""
assert factorial(0) == 1
assert factorial(1) == 1
assert factorial(5) == 120
assert factorial(3) == 6
def test_factorial_negative(self):
"""Test factorial of negative numbers raises error."""
with pytest.raises(ValueError, match="Factorial is not defined for negative numbers"):
factorial(-1)