Skip to content

Commit

Permalink
Implementing ctest-friendly tests for /maths
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramy-Badr-Ahmed committed Oct 9, 2024
1 parent 96909dc commit fa95858
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:

- name: Test
working-directory: ${{env.build_path}}
run: ctest
run: ctest --output-on-failure

- name: Run examples
working-directory: ${{env.build_path}}
Expand Down
12 changes: 12 additions & 0 deletions modules/maths/euclid_gcd.f90
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
!> Module implementing the Euclidean Algorithm for GCD
!!
!! Modified by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
!! in Pull Request: #31
!! https://github.com/TheAlgorithms/Fortran/pull/31
!!
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
!! addressing bugs/corrections to this file. Thank you!
!!
!! Reference: https://en.wikipedia.org/wiki/Euclidean_algorithm

module gcd_module
Expand All @@ -10,6 +18,10 @@ function gcd(a, b) result(val)
integer, value :: a, b
integer :: t, val

! Ensure the GCD is non-negative
a = abs(a)
b = abs(b)

! Euclidean algorithm for GCD
do while (b /= 0)
t = b
Expand Down
16 changes: 14 additions & 2 deletions modules/maths/fibonacci.f90
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
!> Module for Fibonacci series calculations
!!
!! Modified by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
!! in Pull Request: #31
!! https://github.com/TheAlgorithms/Fortran/pull/31
!!
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
!! addressing bugs/corrections to this file. Thank you!
!!
!! Provides both recursive and iterative implementations.
!! Reference: https://en.wikipedia.org/wiki/Fibonacci_number

Expand All @@ -10,7 +18,9 @@ module fibonacci_module
recursive function fib_rec(n) result(f)
integer, intent(in), value :: n
integer :: f
if (n <= 1) then
if (n < 0) then
f = -1 ! signal error condition
else if (n <= 1) then
f = n
else
f = fib_rec(n - 1) + fib_rec(n - 2)
Expand All @@ -22,7 +32,9 @@ function fib_itr(n) result(f)
integer, intent(in) :: n
integer :: f, tmp, f_1
integer :: i
if (n <= 1) then
if (n < 0) then
f = -1 ! signal error condition
else if (n <= 1) then
f = n
else
f_1 = 0
Expand Down
94 changes: 94 additions & 0 deletions tests/maths/eculid_gcd.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
!> Test program for the GCD module
!!
!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
!! in Pull Request: #31
!! https://github.com/TheAlgorithms/Fortran/pull/31
!!
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
!! addressing bugs/corrections to this file. Thank you!
!!
!! This program provides test cases to validate the GCD function in the gcd_module.

program tests_gcd_module
use gcd_module
implicit none
integer :: result, expected

! Run test cases
call test_gcd_positive_numbers()
call test_gcd_with_zero()
call test_gcd_negative_numbers()
call test_gcd_same_numbers()
call test_gcd_large_numbers()

print *, "All tests completed."

contains

! Test case 1: GCD of two positive numbers
subroutine test_gcd_positive_numbers()
integer :: a, b
a = 48
b = 18
expected = 6
result = gcd(a, b)
call assert_test(result, expected, "Test 1: GCD of two positive numbers")
end subroutine test_gcd_positive_numbers

! Test case 2: GCD with one number as zero
subroutine test_gcd_with_zero()
integer :: a, b
a = 0
b = 5
expected = 5
result = gcd(a, b)
call assert_test(result, expected, "Test 2: GCD with one number as zero")
end subroutine test_gcd_with_zero

! Test case 3: GCD of two negative numbers
subroutine test_gcd_negative_numbers()
integer :: a, b
a = -48
b = -18
expected = 6
result = gcd(a, b)
call assert_test(result, expected, "Test 3: GCD of two negative numbers")
end subroutine test_gcd_negative_numbers

! Test case 4: GCD of the same number
subroutine test_gcd_same_numbers()
integer :: a, b
a = 42
b = 42
expected = 42
result = gcd(a, b)
call assert_test(result, expected, "Test 4: GCD of the same number")
end subroutine test_gcd_same_numbers

! Test case 5: GCD of large numbers
subroutine test_gcd_large_numbers()
integer :: a, b
a = 123456
b = 789012
expected = 12
result = gcd(a, b)
call assert_test(result, expected, "Test 5: GCD of large numbers")
end subroutine test_gcd_large_numbers

!> Subroutine to assert the test results
subroutine assert_test(actual, expected, test_name)
integer, intent(in) :: actual, expected
character(len=*), intent(in) :: test_name

if (actual == expected) then
print *, test_name, " PASSED"
else
print *, test_name, " FAILED"
print *, "Expected: ", expected
print *, "Got: ", actual
stop 1
end if

end subroutine assert_test

end program tests_gcd_module
87 changes: 87 additions & 0 deletions tests/maths/factorial.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
!> Test program for factorial functions
!!
!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
!! in Pull Request: #31
!! https://github.com/TheAlgorithms/Fortran/pull/31
!!
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
!! addressing bugs/corrections to this file. Thank you!
!!
!! This program provides test cases to validate the two facotrial functions in the factorial_module.

program tests_factorial
use factorial_module
implicit none

integer :: result, expected

! Run test cases
call test_factorial()
call test_recursive_factorial()

print *, "All tests completed."

contains

! Test case for iterative factorial for known values
subroutine test_factorial()
expected = 120
result = factorial(5)
call assert_test(result, expected, "Test 1: Iterative Factorial of 5")

expected = 1
result = factorial(0)
call assert_test(result, expected, "Test 2: Iterative Factorial of edge case: 0")

expected = 1
result = factorial(1)
call assert_test(result, expected, "Test 3: Iterative Factorial of edge case: 1")

expected = 40320
result = factorial(8)
call assert_test(result, expected, "Test 4: Iterative Factorial of 8")

expected = 720
result = factorial(6)
call assert_test(result, expected, "Test 5: Iterative Factorial of 6")
end subroutine test_factorial

! Test case for recursive factorial for known values
subroutine test_recursive_factorial()
expected = 120
result = recursive_factorial(5)
call assert_test(result, expected, "Test 1: Recursive Factorial of 5")

expected = 1
result = recursive_factorial(0)
call assert_test(result, expected, "Test 2: Recursive Factorial of edge case: 0")

expected = 1
result = recursive_factorial(1)
call assert_test(result, expected, "Test 3: Recursive Factorial of edge case: 1")

expected = 40320
result = recursive_factorial(8)
call assert_test(result, expected, "Test 4: Recursive Factorial of 8")

expected = 720
result = recursive_factorial(6)
call assert_test(result, expected, "Test 5: Recursive Factorial of 6")
end subroutine test_recursive_factorial

!> Subroutine to assert the test results
subroutine assert_test(actual, expected, test_name)
integer, intent(in) :: actual, expected
character(len=*), intent(in) :: test_name

if (actual == expected) then
print *, test_name, " PASSED"
else
print *, test_name, " FAILED"
print *, "Expected: ", expected
print *, "Got: ", actual
stop 1
end if
end subroutine assert_test

end program tests_factorial
121 changes: 121 additions & 0 deletions tests/maths/fibonacci.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
!> Test program for Fibonacci functions
!!
!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
!! in Pull Request: #31
!! https://github.com/TheAlgorithms/Fortran/pull/31
!!
!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
!! addressing bugs/corrections to this file. Thank you!
!!
!! This program provides test cases to validate the two fibonacci functions in the fibonacci_module.

program tests_fibonacci
use fibonacci_module
implicit none

integer :: result, expected

! Run test cases
call test_fib_zero()
call test_fib_one()
call test_fib_two()
call test_fib_three()
call test_fib_five()
call test_fib_thirty()
call test_fib_negative_one()
call test_fib_negative_five()

print *, "All tests completed."

contains

! Test case 1: Fibonacci of 0
subroutine test_fib_zero()
expected = 0
result = fib_rec(0)
call assert_test(result, expected, "Test 1: Fibonacci of 0 (Recursive)")
result = fib_itr(0)
call assert_test(result, expected, "Test 1: Fibonacci of 0 (Iterative)")
end subroutine test_fib_zero

! Test case 2: Fibonacci of 1
subroutine test_fib_one()
expected = 1
result = fib_rec(1)
call assert_test(result, expected, "Test 2: Fibonacci of 1 (Recursive)")
result = fib_itr(1)
call assert_test(result, expected, "Test 2: Fibonacci of 1 (Iterative)")
end subroutine test_fib_one

! Test case 3: Fibonacci of 2
subroutine test_fib_two()
expected = 1
result = fib_rec(2)
call assert_test(result, expected, "Test 3: Fibonacci of 2 (Recursive)")
result = fib_itr(2)
call assert_test(result, expected, "Test 3: Fibonacci of 2 (Iterative)")
end subroutine test_fib_two

! Test case 4: Fibonacci of 3
subroutine test_fib_three()
expected = 2
result = fib_rec(3)
call assert_test(result, expected, "Test 4: Fibonacci of 3 (Recursive)")
result = fib_itr(3)
call assert_test(result, expected, "Test 4: Fibonacci of 3 (Iterative)")
end subroutine test_fib_three

! Test case 5: Fibonacci of 5
subroutine test_fib_five()
expected = 5
result = fib_rec(5)
call assert_test(result, expected, "Test 5: Fibonacci of 5 (Recursive)")
result = fib_itr(5)
call assert_test(result, expected, "Test 5: Fibonacci of 5 (Iterative)")
end subroutine test_fib_five

! Test case 6: Fibonacci of 30
subroutine test_fib_thirty()
expected = 832040
result = fib_rec(30)
call assert_test(result, expected, "Test 5: Fibonacci of 30 (Recursive)")
result = fib_itr(30)
call assert_test(result, expected, "Test 5: Fibonacci of 30 (Iterative)")
end subroutine test_fib_thirty

! Test case 7: Fibonacci of negative input
subroutine test_fib_negative_one()
expected = -1
result = fib_rec(-9)
call assert_test(result, expected, "Test 6: Fibonacci of -1 (Recursive)")
result = fib_itr(-9)
call assert_test(result, expected, "Test 6: Fibonacci of -1 (Iterative)")
end subroutine test_fib_negative_one

! Test case 8: Fibonacci of negative input
subroutine test_fib_negative_five()
expected = -1
result = fib_rec(-9)
call assert_test(result, expected, "Test 7: Fibonacci of -5 (Recursive)")
result = fib_itr(-9)
call assert_test(result, expected, "Test 7: Fibonacci of -5 (Iterative)")
end subroutine test_fib_negative_five

!> Subroutine to assert the test results
subroutine assert_test(actual, expected, test_name)
integer, intent(in) :: actual, expected
character(len=*), intent(in) :: test_name

if (actual == expected) then
print *, test_name, " PASSED"
else
print *, test_name, " FAILED"
print *, "Expected: ", expected
print *, "Got: ", actual
stop 1
end if

end subroutine assert_test

end program tests_fibonacci

0 comments on commit fa95858

Please sign in to comment.