"""Tests for math_utils module"""
import pytest
from farhan.math_utils import factorial, is_prime, fibonacci, gcd


class TestFactorial:
    """Tests for factorial function"""
    
    def test_factorial_zero(self):
        assert factorial(0) == 1
    
    def test_factorial_one(self):
        assert factorial(1) == 1
    
    def test_factorial_five(self):
        assert factorial(5) == 120
    
    def test_factorial_ten(self):
        assert factorial(10) == 3628800
    
    def test_factorial_negative_raises_error(self):
        with pytest.raises(ValueError):
            factorial(-1)
    
    def test_factorial_non_integer_raises_error(self):
        with pytest.raises(TypeError):
            factorial(3.5)


class TestIsPrime:
    """Tests for is_prime function"""
    
    def test_prime_two(self):
        assert is_prime(2) == True
    
    def test_prime_seventeen(self):
        assert is_prime(17) == True
    
    def test_not_prime_four(self):
        assert is_prime(4) == False
    
    def test_not_prime_one(self):
        assert is_prime(1) == False
    
    def test_not_prime_zero(self):
        assert is_prime(0) == False
    
    def test_not_prime_negative(self):
        assert is_prime(-5) == False


class TestFibonacci:
    """Tests for fibonacci function"""
    
    def test_fibonacci_zero(self):
        assert fibonacci(0) == []
    
    def test_fibonacci_one(self):
        assert fibonacci(1) == [0]
    
    def test_fibonacci_two(self):
        assert fibonacci(2) == [0, 1]
    
    def test_fibonacci_seven(self):
        assert fibonacci(7) == [0, 1, 1, 2, 3, 5, 8]
    
    def test_fibonacci_negative_raises_error(self):
        with pytest.raises(ValueError):
            fibonacci(-1)


class TestGCD:
    """Tests for gcd function"""
    
    def test_gcd_basic(self):
        assert gcd(48, 18) == 6
    
    def test_gcd_coprime(self):
        assert gcd(17, 5) == 1
    
    def test_gcd_same_number(self):
        assert gcd(7, 7) == 7
    
    def test_gcd_with_zero(self):
        assert gcd(10, 0) == 10
    
    def test_gcd_negative_numbers(self):
        assert gcd(-48, 18) == 6
