diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a730d94..0385bba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,6 +79,7 @@ jobs: CMAKE_PREFIX_PATH=${INSTALL_DIR} cmake -B ${BUILD_DIR} -G Ninja test/export cmake --build ${BUILD_DIR} ${BUILD_DIR}/app/testapp + ${BUILD_DIR}/app/testapp_fpp ${BUILD_DIR}/app/testapp_fypp rm -rf ${BUILD_DIR} diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index c4c0588..d6aa13a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -30,7 +30,7 @@ target_sources( ) target_link_libraries(fortuno_example_testapp PRIVATE fortuno_example_mylib Fortuno::fortuno_serial) - +add_subdirectory(fpp) if (FYPP) add_subdirectory(fypp) -endif () \ No newline at end of file +endif () diff --git a/example/fpp/CMakeLists.txt b/example/fpp/CMakeLists.txt new file mode 100644 index 0000000..6f3a6f9 --- /dev/null +++ b/example/fpp/CMakeLists.txt @@ -0,0 +1,37 @@ +# This file is part of Fortuno. +# Licensed under the BSD-2-Clause Plus Patent license. +# SPDX-License-Identifier: BSD-2-Clause-Patent + +list(APPEND CMAKE_MESSAGE_CONTEXT Fpp) + +add_library(fortuno_example_fpp_mylib) +set_target_properties( + fortuno_example_fpp_mylib PROPERTIES + OUTPUT_NAME mylib +) +target_sources( + fortuno_example_fpp_mylib PRIVATE + mylib_fpp.f90 +) + +add_executable(fortuno_example_fpp_testapp) +set_target_properties( + fortuno_example_fpp_testapp PROPERTIES + OUTPUT_NAME testapp_fpp +) +target_sources( + fortuno_example_fpp_testapp PRIVATE + simple_fpp_tests.F90 + testapp_fpp.f90 +) +target_link_libraries( + fortuno_example_fpp_testapp PRIVATE + fortuno_example_fpp_mylib + Fortuno::fortuno_serial + Fortuno::fortuno_include_dir +) +# GNU compiler (as of version 13.2) needs special flag to cope with extra long lines +if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + set(fc_line_length_option "--free-line-length-none") +endif () +target_compile_options(fortuno_example_fpp_testapp PRIVATE "${fc_line_length_option}") diff --git a/example/fpp/mylib_fpp.f90 b/example/fpp/mylib_fpp.f90 new file mode 100644 index 0000000..ccd7daa --- /dev/null +++ b/example/fpp/mylib_fpp.f90 @@ -0,0 +1,34 @@ +! This file is part of Fortuno. +! Licensed under the BSD-2-Clause Plus Patent license. +! SPDX-License-Identifier: BSD-2-Clause-Patent + +!> Demo module/library to be tested +module mylib_fpp + implicit none + + private + public :: factorial + +contains + + !> Calculates the factorial of a number + function factorial(nn) result(fact) + + !> Number to calculate the factorial of + integer, intent(in) :: nn + + !> Factorial (note, there is no check made for integer overflow!) + integer :: fact + + integer :: ii + + fact = 1 + do ii = 2, nn + fact = fact * ii + end do + ! We create a "bug" which manifests only for certain input values + if (nn == 2 .or. nn > 10) fact = fact - 1 + + end function factorial + +end module mylib_fpp diff --git a/example/fpp/simple_fpp_tests.F90 b/example/fpp/simple_fpp_tests.F90 new file mode 100644 index 0000000..1c21bb7 --- /dev/null +++ b/example/fpp/simple_fpp_tests.F90 @@ -0,0 +1,54 @@ +! This file is part of Fortuno. +! Licensed under the BSD-2-Clause Plus Patent license. +! SPDX-License-Identifier: BSD-2-Clause-Patent + +#include "fortuno_serial.fpp" + +module simple_fpp_tests + use mylib_fpp, only : factorial + use fortuno_serial, only : is_equal, test => serial_case_item, suite => serial_suite_item,& + & test_item + implicit none + + private + public :: simple_fpp_test_items + +contains + + ! Test: 0! = 1 + subroutine test_factorial_0() + CHECK(factorial(0) == 1) + end subroutine test_factorial_0 + + ! Test: 1! = 1 + subroutine test_factorial_1() + CHECK(factorial(1) == 1) + end subroutine test_factorial_1 + + ! Test: 2! = 2 (will fail due to the bug in the implementation of the factorial function) + subroutine test_factorial_2() + ! Two failing checks, you should see info about both in the output + CHECK_MSG(is_equal(factorial(2), 2), "Test failed for demonstration purposes") + CHECK(factorial(2) == 2) + end subroutine test_factorial_2 + + + ! Returns the tests from this module. + function simple_fpp_test_items() result(testitems) + type(test_item), allocatable :: testitems(:) + + testitems = [& + ! Adding a single test not belonging to any test suite + test("factorial_0", test_factorial_0),& + + ! Packing further tests into a suite in order to introduce more structure + ! (e.g. running only tests being part of a given suite) + suite("simple", [& + test("factorial_1", test_factorial_1),& + test("factorial_2", test_factorial_2)& + ])& + ] + + end function simple_fpp_test_items + +end module simple_fpp_tests diff --git a/example/fpp/testapp_fpp.f90 b/example/fpp/testapp_fpp.f90 new file mode 100644 index 0000000..0c94ed6 --- /dev/null +++ b/example/fpp/testapp_fpp.f90 @@ -0,0 +1,17 @@ +! This file is part of Fortuno. +! Licensed under the BSD-2-Clause Plus Patent license. +! SPDX-License-Identifier: BSD-2-Clause-Patent + +!> Test app with command line interface, collecting and executing the tests. +program testapp_fpp + use fortuno_serial, only : execute_serial_cmd_app + use simple_fpp_tests, only : simple_fpp_test_items + implicit none + + call execute_serial_cmd_app(& + testitems=[& + simple_fpp_test_items()& + ]& + ) + +end program testapp_fpp diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index a320a9d..7e49f1c 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -14,7 +14,7 @@ add_library(Fortuno::fortuno_include_dir ALIAS fortuno_include_dir) if (FORTUNO_INSTALL) install( - FILES fortuno_serial.fypp + FILES fortuno_serial.fpp fortuno_serial.fypp DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT Fortuno_development ) @@ -22,4 +22,4 @@ if (FORTUNO_INSTALL) TARGETS fortuno_include_dir EXPORT FortunoTargets ) -endif () \ No newline at end of file +endif () diff --git a/include/fortuno_serial.fpp b/include/fortuno_serial.fpp new file mode 100644 index 0000000..4fe8c8c --- /dev/null +++ b/include/fortuno_serial.fpp @@ -0,0 +1,34 @@ +! This file is part of Fortuno. +! Licensed under the BSD-2-Clause Plus Patent license. +! SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifndef __FORTUNO_SERIAL_FPP__ +#define __FORTUNO_SERIAL_FPP__ + +#define CHECK(cond)\ + block;\ + use fortuno_serial, only : serial_check;\ + call serial_check(cond, file=__FILE__, line=__LINE__);\ + end block; + +#define CHECK_MSG(cond, msg)\ + block;\ + use fortuno_serial, only : serial_check;\ + call serial_check(cond, msg, file=__FILE__, line=__LINE__);\ + end block; + +#define ASSERT(cond)\ + block;\ + use fortuno_serial, only : serial_check, serial_check_failed;\ + call serial_check(cond, file=__FILE__, line=__LINE__);\ + if (serial_check_failed) return;\ + end block; + +#define ASSERT_MSG(cond, msg)\ + block;\ + use fortuno_serial, only : serial_check, serial_check_failed;\ + call serial_check(cond, msg, file=__FILE__, line=__LINE__);\ + if (serial_check_failed) return;\ + end block; + +#endif diff --git a/include/fortuno_serial.fypp b/include/fortuno_serial.fypp index e0d0fc7..56253b3 100644 --- a/include/fortuno_serial.fypp +++ b/include/fortuno_serial.fypp @@ -13,7 +13,7 @@ #! Imports the prerequisites needed by the macro definitions in this file #:def FORTUNO_SERIAL_IMPORTS() - use fortuno_serial, only : serial_case_item, serial_check, serial_failed + use fortuno_serial, only : serial_case_item, serial_check, serial_check_failed #:enddef @@ -81,7 +81,7 @@ #! #:def ASSERT(cond, **kwargs) $:CHECK(cond, **kwargs) -if (serial_failed()) return +if (serial_check_failed()) return #:enddef diff --git a/test/export/app/CMakeLists.txt b/test/export/app/CMakeLists.txt index f55fe28..c39845b 100644 --- a/test/export/app/CMakeLists.txt +++ b/test/export/app/CMakeLists.txt @@ -3,10 +3,18 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent add_executable(testapp) - target_sources(testapp PRIVATE testapp.f90) target_link_libraries(testapp PRIVATE Fortuno::fortuno_serial) +add_executable(testapp_fpp) +target_sources(testapp_fpp PRIVATE testapp_fpp.F90) +target_link_libraries(testapp_fpp PRIVATE Fortuno::fortuno_serial Fortuno::fortuno_include_dir) +# GNU compiler (as of version 13.2) needs special flag to cope with extra long lines +if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + set(fc_line_length_option "--free-line-length-none") +endif () +target_compile_options(testapp_fpp PRIVATE "${fc_line_length_option}") + if (FYPP) add_executable(testapp_fypp) diff --git a/test/export/app/testapp_fpp.F90 b/test/export/app/testapp_fpp.F90 new file mode 100644 index 0000000..4b36ebc --- /dev/null +++ b/test/export/app/testapp_fpp.F90 @@ -0,0 +1,43 @@ +! This file is part of Fortuno. +! Licensed under the BSD-2-Clause Plus Patent license. +! SPDX-License-Identifier: BSD-2-Clause-Patent + +#include "fortuno_serial.fpp" + +!> Unit tests +module testapp_fpp_tests + use fortuno_serial, only : is_equal, test => serial_case_item, test_item + implicit none + + private + public :: test_items + +contains + + + subroutine test_success() + CHECK(is_equal(1, 1)) + end subroutine test_success + + + function test_items() result(testitems) + type(test_item), allocatable :: testitems(:) + + testitems = [& + test("success", test_success)& + ] + + end function test_items + +end module testapp_fpp_tests + + +!> Test app driving Fortuno unit tests +program testapp_fpp + use testapp_fpp_tests, only : test_items + use fortuno_serial, only : execute_serial_cmd_app + implicit none + + call execute_serial_cmd_app(testitems=test_items()) + +end program testapp_fpp