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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [main, dev]
branches: [main, master, dev]
pull_request:
branches: [main, dev]
branches: [main, master, dev]

jobs:
lint-and-type-check:
Expand Down
52 changes: 52 additions & 0 deletions calculator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
A simple calculator module for testing CI/CD workflows.
"""
from typing import Union


class Calculator:
"""Basic calculator with arithmetic operations."""

@staticmethod
def add(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
"""Add two numbers."""
return a + b

@staticmethod
def subtract(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
"""Subtract b from a."""
return a - b

@staticmethod
def multiply(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
"""Multiply two numbers."""
return a * b

@staticmethod
def divide(a: Union[int, float], b: Union[int, float]) -> float:
"""Divide a by b."""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b

@staticmethod
def power(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
"""Raise a to the power of b."""
return a**b


def main() -> None:
"""Demo usage of the calculator."""
calc = Calculator()

print("Calculator Demo")
print("=" * 40)
print(f"5 + 3 = {calc.add(5, 3)}")
print(f"10 - 4 = {calc.subtract(10, 4)}")
print(f"6 * 7 = {calc.multiply(6, 7)}")
print(f"15 / 3 = {calc.divide(15, 3)}")
print(f"2 ^ 8 = {calc.power(2, 8)}")


if __name__ == "__main__":
main()
12 changes: 8 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Add your Python dependencies here
# Example:
# requests>=2.28.0
# flask>=2.3.0
# Testing dependencies
pytest>=7.4.0
pytest-cov>=4.1.0

# Code quality tools
black>=23.0.0
pylint>=3.0.0
mypy>=1.5.0
32 changes: 32 additions & 0 deletions string_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
String utility functions for testing CI/CD workflows.
"""


def reverse_string(text: str) -> str:
"""Reverse a string."""
return text[::-1]


def is_palindrome(text: str) -> bool:
"""Check if a string is a palindrome."""
cleaned = "".join(c.lower() for c in text if c.isalnum())
return cleaned == cleaned[::-1]


def count_vowels(text: str) -> int:
"""Count the number of vowels in a string."""
vowels = "aeiouAEIOU"
return sum(1 for char in text if char in vowels)


def title_case(text: str) -> str:
"""Convert string to title case."""
return " ".join(word.capitalize() for word in text.split())


def truncate(text: str, max_length: int, suffix: str = "...") -> str:
"""Truncate string to max length with optional suffix."""
if len(text) <= max_length:
return text
return text[: max_length - len(suffix)] + suffix
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests package."""
56 changes: 56 additions & 0 deletions tests/test_calculator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Tests for the calculator module.
"""
import pytest
from calculator import Calculator


class TestCalculator:
"""Test suite for Calculator class."""

def test_add_positive_numbers(self):
"""Test addition of positive numbers."""
assert Calculator.add(5, 3) == 8
assert Calculator.add(10, 20) == 30

def test_add_negative_numbers(self):
"""Test addition with negative numbers."""
assert Calculator.add(-5, -3) == -8
assert Calculator.add(-10, 5) == -5

def test_subtract(self):
"""Test subtraction."""
assert Calculator.subtract(10, 3) == 7
assert Calculator.subtract(5, 10) == -5

def test_multiply(self):
"""Test multiplication."""
assert Calculator.multiply(5, 3) == 15
assert Calculator.multiply(-2, 4) == -8
assert Calculator.multiply(0, 100) == 0

def test_divide(self):
"""Test division."""
assert Calculator.divide(10, 2) == 5.0
assert Calculator.divide(7, 2) == 3.5

def test_divide_by_zero(self):
"""Test that division by zero raises ValueError."""
with pytest.raises(ValueError, match="Cannot divide by zero"):
Calculator.divide(10, 0)

def test_power(self):
"""Test power operation."""
assert Calculator.power(2, 3) == 8
assert Calculator.power(5, 2) == 25
assert Calculator.power(10, 0) == 1

def test_add_floats(self):
"""Test addition with floating point numbers."""
result = Calculator.add(0.1, 0.2)
assert pytest.approx(result, 0.001) == 0.3

def test_multiply_by_zero(self):
"""Test multiplication by zero."""
assert Calculator.multiply(100, 0) == 0
assert Calculator.multiply(0, 0) == 0
72 changes: 72 additions & 0 deletions tests/test_string_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
Tests for string utility functions.
"""
import pytest
from string_utils import (
reverse_string,
is_palindrome,
count_vowels,
title_case,
truncate,
)


class TestStringUtils:
"""Test suite for string utility functions."""

def test_reverse_string(self):
"""Test string reversal."""
assert reverse_string("hello") == "olleh"
assert reverse_string("Python") == "nohtyP"
assert reverse_string("") == ""
assert reverse_string("a") == "a"

def test_is_palindrome_simple(self):
"""Test palindrome detection with simple strings."""
assert is_palindrome("racecar") is True
assert is_palindrome("hello") is False
assert is_palindrome("A") is True

def test_is_palindrome_with_spaces(self):
"""Test palindrome detection ignoring spaces and case."""
assert is_palindrome("A man a plan a canal Panama") is True
assert is_palindrome("race a car") is False

def test_is_palindrome_empty(self):
"""Test palindrome with empty string."""
assert is_palindrome("") is True

def test_count_vowels(self):
"""Test vowel counting."""
assert count_vowels("hello") == 2
assert count_vowels("AEIOU") == 5
assert count_vowels("xyz") == 0
assert count_vowels("") == 0
assert count_vowels("Python Programming") == 4

def test_title_case(self):
"""Test title case conversion."""
assert title_case("hello world") == "Hello World"
assert title_case("python programming") == "Python Programming"
assert title_case("ALREADY UPPER") == "Already Upper"
assert title_case("") == ""

def test_truncate_short_string(self):
"""Test truncation with string shorter than max length."""
assert truncate("hello", 10) == "hello"
assert truncate("test", 4) == "test"

def test_truncate_long_string(self):
"""Test truncation with string longer than max length."""
assert truncate("hello world", 8) == "hello..."
assert truncate("this is a long string", 10) == "this is..."

def test_truncate_custom_suffix(self):
"""Test truncation with custom suffix."""
assert truncate("hello world", 8, suffix=">>") == "hello >>
assert truncate("testing", 5, suffix="!") == "test!"

def test_truncate_edge_cases(self):
"""Test truncation edge cases."""
assert truncate("", 5) == ""
assert truncate("hi", 2) == "hi"
Loading