diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index f9a80a76..97815272 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -2,9 +2,10 @@ name: Build and Deploy Documentation on: [push, pull_request] + jobs: Build: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -13,13 +14,13 @@ jobs: - name: Install Dependencies Ubuntu run: | sudo apt-get update - sudo apt install -y python-dev python build-essential graphviz - sudo pip install ford + sudo apt install -y python3-dev python3 build-essential graphviz + sudo pip install ford markdown==3.3.4 - name: Build Developer Documenation run: | cd doc - ford ford-documentation.md + ford ford.md - name: Upload Documentation uses: actions/upload-artifact@v2 diff --git a/doc/ford-documentation.md b/doc/ford.md similarity index 100% rename from doc/ford-documentation.md rename to doc/ford.md diff --git a/fpm.toml b/fpm.toml index f675fcb5..28a1c475 100644 --- a/fpm.toml +++ b/fpm.toml @@ -1,17 +1,9 @@ name = "sourcery" -version = "1.0.0" +version = "3.1.0" license = "BSD" author = ["Damian Rouson"] -maintainer = "damian@sourceryinstitute.org" -copyright = "2020 Sourcery Institute" +maintainer = "damian@archaeologic.codes" +copyright = "2020-2022 Sourcery Institute" [dependencies] -assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.0.0"} - -[dev-dependencies] -vegetables = {git = "https://gitlab.com/everythingfunctional/vegetables", tag = "v7.2.0"} - -[[test]] -name="unit" -source-dir="tests" -main="main.f90" +assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.4.0"} diff --git a/src/test_m.F90 b/src/test_m.F90 new file mode 100644 index 00000000..00ccf565 --- /dev/null +++ b/src/test_m.F90 @@ -0,0 +1,44 @@ +module test_m + !! Define an abstract test_t type with deferred bindings ("subject" and "results") + !! used by a type-bound procedure ("report") for reporting test results. The "report" + !! procedure thus represents an implementation of the Template Method pattern. + use test_result_m, only : test_result_t + implicit none + + private + public :: test_t, test_result_t + + type, abstract :: test_t + !! Facilitate testing and test reporting + contains + procedure(subject_interface), nopass, deferred :: subject + procedure(results_interface), nopass, deferred :: results + procedure :: report + end type + + abstract interface + + pure function subject_interface() result(specimen) + !! The result is the name of the test specimen (the subject of testing) + character(len=:), allocatable :: specimen + end function + + function results_interface() result(test_results) + !! The result is an array of test results for subsequent reporting in the "report" type-bound procedure + import test_result_t + type(test_result_t), allocatable :: test_results(:) + end function + + end interface + + interface + + module subroutine report(test) + !! Report test results + implicit none + class(test_t), intent(in) :: test + end subroutine + + end interface + +end module test_m diff --git a/src/test_result_m.f90 b/src/test_result_m.f90 new file mode 100644 index 00000000..8ce3f5fe --- /dev/null +++ b/src/test_result_m.f90 @@ -0,0 +1,40 @@ +module test_result_m + !! Define an abstraction for describing test intentions and results + implicit none + + private + public :: test_result_t + + type test_result_t + !! Encapsulate test descriptions and outcomes and reporting + private + character(len=:), allocatable :: description_ + logical passed_ + contains + procedure :: characterize + end type + + interface test_result_t + + pure module function construct(description, passed) result(test_result) + !! The result is a test_result_t object with the components defined by the dummy arguments + implicit none + character(len=*), intent(in) :: description + logical, intent(in) :: passed + type(test_result_t) test_result + end function + + end interface + + interface + + pure module function characterize(self) result(characterization) + !! The result is a character description of the test and its outcome + implicit none + class(test_result_t), intent(in) :: self + character(len=:), allocatable :: characterization + end function + + end interface + +end module test_result_m diff --git a/src/test_result_s.f90 b/src/test_result_s.f90 new file mode 100644 index 00000000..171a7d26 --- /dev/null +++ b/src/test_result_s.f90 @@ -0,0 +1,15 @@ +submodule(test_result_m) test_result_s + implicit none + +contains + + module procedure construct + test_result%description_ = description + test_result%passed_ = passed + end procedure + + module procedure characterize + characterization = merge("passes on ", "FAILS on ", self%passed_) // self%description_ // "." + end procedure + +end submodule test_result_s diff --git a/src/test_s.F90 b/src/test_s.F90 new file mode 100644 index 00000000..12e16dfc --- /dev/null +++ b/src/test_s.F90 @@ -0,0 +1,29 @@ +submodule(test_m) test_s +#ifdef XLF + use test_result_m, only : test_result_t +#endif + implicit none + +contains + + module procedure report + integer i +#ifdef XLF + type(test_result_t), allocatable :: test_results(:) + test_results = test%results() +#else + associate(test_results => test%results()) +#endif + + print * + print *, test%subject() + + do i=1,size(test_results) + print *," ",test_results(i)%characterize() + end do +#ifndef XLF + end associate +#endif + end procedure + +end submodule test_s diff --git a/tests/data_partition_test.f90 b/test/data_partition_test.f90 similarity index 50% rename from tests/data_partition_test.f90 rename to test/data_partition_test.f90 index 34f5b2f2..a8c2136c 100644 --- a/tests/data_partition_test.f90 +++ b/test/data_partition_test.f90 @@ -1,63 +1,56 @@ module data_partition_test - !! author: Damian Rouson - !! - !! summary: verify data partitioning across images and data gathering - use vegetables, only: & - result_t, example_t, input_t, integer_input_t, test_item_t, & ! types - describe, it, assert_equals, assert_that ! functions - use data_partition_m, only : data_partition_t - use iso_fortran_env, only : real64 - implicit none - - private - public :: test_data_partition + !! verify data partitioning across images and data gathering + use data_partition_m, only : data_partition_t + use test_m, only : test_t, test_result_t + use iso_fortran_env, only : real64 + implicit none - type(data_partition_t) partition - integer, parameter :: num_particles=31, gatherer=1, num_steps=9, dummy=0 + private + public :: data_partition_test_t + + type, extends(test_t) :: data_partition_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type + + type(data_partition_t) partition + integer, parameter :: num_particles=31, gatherer=1, num_steps=9, dummy=0 contains - function test_data_partition() result(tests) - type(test_item_t) tests + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The data_partition_t type" + end function + + function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) - call partition%define_partitions( cardinality=num_particles) + call partition%define_partitions(cardinality=num_particles) associate( me=>this_image() ) associate( my_first=>partition%first(me), my_last=>partition%last(me) ) - tests = describe( & - "data_partition class", & - [it( & - "partitions data in nearly even blocks", & - verify_block_partitioning), & - it( & - "all data partitioned across all images without data loss", & - verify_all_particles_partitioned), & - it( & - "1D real array gathered on all images", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_all_gather_1D_real_array), & - it( & - "dimension 1 of 2D real array gathered on all images witout dim argument", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_all_gather_2D_real_array), & - it( & - "dimension 1 of 2D real array gathered on all images with dim argument", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_all_gather_2D_real_array_dim1), & - it( & - "dimension 1 of 2D real array gathered onto result_image with dim argument", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_gather_2D_real_array_dim1)]) - + test_results = [ & + test_result_t("partitioning data in nearly even blocks", verify_block_partitioning()), & + test_result_t("partitioning all data across all images without data loss", verify_all_particles_partitioned()), & + test_result_t("gathering a 1D real array onto all images", verify_all_gather_1D_real_array()), & + test_result_t("gathering dimension 1 of 2D real array onto all images witout dim argument", & + verify_all_gather_2D_real_array()), & + test_result_t("gathering dimension 1 of 2D real array onton all images with dim argument", & + verify_all_gather_2D_real_array_dim1()), & + test_result_t("gathering dimension 1 of 2D real array onto result_image with dim argument", & + verify_gather_2D_real_array_dim1()) & + ] end associate end associate end function - function verify_block_partitioning() result(result_) + function verify_block_partitioning() result(test_passes) !! Verify that the data is partitioned across images evenly to !! within a difference of one datum between any two images. type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer my_particles associate( me=>this_image() ) @@ -65,91 +58,72 @@ function verify_block_partitioning() result(result_) my_particles = my_last - my_first + 1 associate( ni=>num_images() ) associate( quotient=>num_particles/ni, remainder=>mod(num_particles,ni) ) - result_ = assert_equals( quotient + merge(1, 0, me<=remainder), my_particles, "block distribution" ) + test_passes = quotient + merge(1, 0, me<=remainder) == my_particles end associate end associate end associate end associate end function - function verify_all_particles_partitioned() result(result_) + function verify_all_particles_partitioned() result(test_passes) !! Verify that the number of particles on each image sums to the !! total number of particles distributed. type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer particles associate(me => this_image()) associate( my_first=>partition%first(me), my_last=>partition%last(me) ) particles = my_last - my_first + 1 call co_sum(particles) - result_ = assert_equals(num_particles, particles, "all particles distributed" ) + test_passes = num_particles == particles end associate end associate end function - function verify_all_gather_1D_real_array(unused) result(result_) + function verify_all_gather_1D_real_array() result(test_passes) type(data_partition_t) partition - class(input_t), intent(in) :: unused - type(result_t) result_ + logical test_passes real(real64) :: particle_scalar(num_particles) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) - particle_scalar(first:last) = expected !! values to be gathered particle_scalar(1:first-1) = junk !! values to be overwritten by the gather particle_scalar(last+1:) = junk !! values to be overwritten by the gather - call partition%gather(particle_scalar) - - result_ = assert_that( all(particle_scalar==expected), "real 1D array all-gathered" ) - + test_passes = all(particle_scalar==expected) end associate end associate end function - function verify_all_gather_2D_real_array(unused) result(result_) - class(input_t), intent(in) :: unused + function verify_all_gather_2D_real_array() result(test_passes) type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer, parameter :: vec_space_dim=3 real(real64) particle_vector(vec_space_dim, num_particles) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) particle_vector(:, first:last) = expected !! values to be gathered particle_vector(:, 1:first-1) = junk !! values to be overwritten by the gather particle_vector(:, last+1:) = junk !! values to be overwritten by the gather - call partition%gather(particle_vector) - - result_ = assert_that(all(particle_vector==expected), "real 2D array all-gathered implicitly along dimension 1" ) - + test_passes = all(particle_vector==expected) end associate end associate end function - function verify_all_gather_2D_real_array_dim1(unused) result(result_) - class(input_t), intent(in) :: unused + function verify_all_gather_2D_real_array_dim1() result(test_passes) type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer, parameter :: vec_space_dim=3 real(real64) :: vector_transpose(num_particles, vec_space_dim) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) @@ -159,23 +133,19 @@ function verify_all_gather_2D_real_array_dim1(unused) result(result_) call partition%gather( vector_transpose, dim=1) - result_ = assert_that(all(vector_transpose==expected), "vector_transpose gathered explicitly along dimension 1" ) + test_passes= all(vector_transpose==expected) end associate end associate end function - function verify_gather_2D_real_array_dim1(unused) result(result_) - class(input_t), intent(in) :: unused + function verify_gather_2D_real_array_dim1() result(test_passes) type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer, parameter :: vec_space_dim=3 real(real64) :: vector_transpose(num_particles, vec_space_dim) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) @@ -186,12 +156,12 @@ function verify_gather_2D_real_array_dim1(unused) result(result_) call partition%gather( vector_transpose, result_image=gatherer, dim=1) if (me==gatherer) then - result_ = assert_that(all(vector_transpose==expected), "all( particle_vector==expected)") + test_passes = all(vector_transpose==expected) else - result_ = & - assert_that(all(vector_transpose(1:first-1,:)==junk), "lower transpose data unchanged)") .and. & - assert_that(all(vector_transpose(first:last,:)==expected), "expected transpose data gathered") .and. & - assert_that(all(vector_transpose(last+1:,:)==junk), "upper transpose data unchanged)" ) + test_passes = & + all(vector_transpose(1:first-1,:)==junk) .and. & + all(vector_transpose(first:last,:)==expected) .and. & + all(vector_transpose(last+1:,:)==junk) end if end associate diff --git a/test/formats_test.f90 b/test/formats_test.f90 new file mode 100644 index 00000000..d6216f02 --- /dev/null +++ b/test/formats_test.f90 @@ -0,0 +1,71 @@ +module formats_test + !! Verify that format strings provide the desired formatting + use formats_m, only : separated_values + use test_m, only : test_t, test_result_t + implicit none + + private + public :: formats_test_t + + type, extends(test_t) :: formats_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type + +contains + + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The csv format" + end function + + pure function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) + + test_results = [ & + test_result_t("yielding a comma-separated list of real numbers", check_csv_reals()), & + test_result_t("yielding a space-separated list of complex numbers", check_space_separated_complex()), & + test_result_t("yielding a comma- and space-separated list of character values", check_csv_character()), & + test_result_t("yielding a new-line-separated list of integer numbers", check_new_line_separated_integers()) & + ] + end function + + pure function check_csv_reals() result(test_passes) + logical test_passes + character(len=*), parameter :: expected_output = "0.00000000,1.00000000,2.00000000" + character(len=len(expected_output)) captured_output + + write(captured_output, fmt = separated_values(separator=",", mold=[integer::])) [0.,1.,2.] + test_passes = expected_output == captured_output + end function + + pure function check_space_separated_complex() result(test_passes) + logical test_passes + character(len=*), parameter :: expected_output = "(0.00000000,1.00000000) (1.00000000,0.00000000)" + character(len=len(expected_output)) captured_output + + write(captured_output, fmt = separated_values(separator=" ", mold=[complex::])) [(0.,1.),(1.,0.)] + test_passes = expected_output == captured_output + end function + + pure function check_new_line_separated_integers() result(test_passes) + logical test_passes + character(len=*), parameter :: expected_output = ( "0" // new_line("") // "1" //new_line("") // "2") + character(len=len(expected_output)) captured_output + + write(captured_output, fmt = separated_values(separator=new_line(""), mold=[integer::])) [0,1,2] + test_passes = captured_output == "0" // new_line("") // "1" //new_line("") // "2" + end function + + pure function check_csv_character() result(test_passes) + logical test_passes + integer, parameter :: num_spaces=3 + character(len=*), parameter :: expected_output = "Yodel, Ay, Hee, Hoo!" + character(len=len(expected_output)+num_spaces) captured_output + + write(captured_output, fmt = separated_values(separator=", ", mold=[integer::])) "Yodel", "Ay", "Hee", "Hoo!" + test_passes= expected_output == captured_output + end function + +end module formats_test diff --git a/test/main.f90 b/test/main.f90 new file mode 100644 index 00000000..ac32dafd --- /dev/null +++ b/test/main.f90 @@ -0,0 +1,17 @@ +program main + use user_defined_collectives_test, only : collectives_test_t + use data_partition_test, only : data_partition_test_t + use object_m_test, only : object_test_t + use formats_test, only : formats_test_t + implicit none + + type(data_partition_test_t) data_partition_test + type(collectives_test_t) collectives_test + type(object_test_t) object_test + type(formats_test_t) formats_test + + call data_partition_test%report() + call collectives_test%report() + call object_test%report() + call formats_test%report() +end program diff --git a/test/object_m_test.f90 b/test/object_m_test.f90 new file mode 100644 index 00000000..a81d1b21 --- /dev/null +++ b/test/object_m_test.f90 @@ -0,0 +1,78 @@ +module object_m_test + !! Verify object pattern asbtract parent + use test_m, only : test_t, test_result_t + use object_m, only : object_t + implicit none + + private + public :: object_test_t + + type, extends(test_t) :: object_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type + + type, extends(object_t) :: subject_t + contains + procedure write_formatted + end type + +contains + + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The object_m type" + end function + + pure function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) + + test_results = [ & + test_result_t("object being .not. user_defined() if it is only default-initialized", check_default_initialization()), & + test_result_t("object being user_defined() after call to mark_as_defined", check_mark_as_defined()) & + ] + end function + + pure function check_default_initialization() result(passed) + !! Verify that user_defined() is .false. for a default-initialied object + class(object_t), allocatable :: object + logical passed + + allocate(subject_t :: object) + passed = .not. object%user_defined() + end function + + pure function check_mark_as_defined() result(passed) + !! Verify that mark_as_defined results in user_defined() being .true. + class(object_t), allocatable :: object + logical passed + + allocate(subject_t :: object) + call object%mark_as_defined + passed = object%user_defined() + end function + + subroutine write_formatted(self, unit, iotype, v_list, iostat, iomsg) + class(subject_t), intent(in) :: self + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + + select case(iotype) + case('LISTDIRECTED') + write(unit,*) self%user_defined() + iostat = 0 + iomsg = "" + case default + iostat = -1 + iomsg = "object_m_test: subject_t%write_formatted iotype received unsupported iotype " // iotype + end select + + associate( unused => v_list) + end associate + end subroutine + +end module object_m_test diff --git a/test/user_defined_collectives_test.f90 b/test/user_defined_collectives_test.f90 new file mode 100644 index 00000000..9adad57b --- /dev/null +++ b/test/user_defined_collectives_test.f90 @@ -0,0 +1,47 @@ +module user_defined_collectives_test + use user_defined_collectives_m, only : co_all + use test_m, only : test_t, test_result_t + implicit none + + private + public :: collectives_test_t + + type, extends(test_t) :: collectives_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type + +contains + + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The co_all subroutine" + end function + + function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) + + test_results = [ & + test_result_t("setting all arguments to .true. when previously .true. on all images", check_co_all_with_all_true()), & + test_result_t("setting all arguments to .false. when previously .false. on image 1", check_co_all_with_one_false()) & + ] + end function + + function check_co_all_with_all_true() result(test_passed) + logical test_passed, all_true + + all_true=.true. + call co_all(all_true) + test_passed = all_true + end function + + function check_co_all_with_one_false() result(test_passed) + logical test_passed, all_true + + all_true = merge(.false., .true., this_image()==1) + call co_all(all_true) + test_passed = .not. all_true + end function + +end module user_defined_collectives_test diff --git a/tests/formats_test.f90 b/tests/formats_test.f90 deleted file mode 100644 index 24719dd8..00000000 --- a/tests/formats_test.f90 +++ /dev/null @@ -1,80 +0,0 @@ -module formats_test - - !! author: Damian Rouson - !! - !! summary: verify that format strings provide the desired formatting - use vegetables, only: & - result_t, test_item_t, & ! types - describe, it, assert_equals ! functions - use formats_m, only : separated_values - implicit none - - private - public :: test_object - -contains - - function test_object() result(tests) - type(test_item_t) tests - - tests = describe( & - "csv format", & - [it( & - "yields a comma-separated list of real numbers", & - check_csv_reals), & - it( & - "yields a space-separated list of complex numbers", & - check_space_separated_complex), & - it( & - "yields a comma- and space-separated list of character values", & - check_cssv_character), & - it( & - "yields a new-line-separated list of integer numbers", & - check_new_line_separated_integers)]) - end function - - function check_csv_reals() result(result_) - type(result_t) result_ - character(len=*), parameter :: expected_output = "0.00000000,1.00000000,2.00000000" - character(len=len(expected_output)) captured_output - - write(captured_output, fmt = separated_values(separator=",", mold=[integer::])) [0.,1.,2.] - - result_ = assert_equals(expected_output, captured_output) - end function - - function check_space_separated_complex() result(result_) - type(result_t) result_ - - character(len=*), parameter :: expected_output = "(0.00000000,1.00000000) (1.00000000,0.00000000)" - character(len=len(expected_output)) captured_output - - write(captured_output, fmt = separated_values(separator=" ", mold=[complex::])) [(0.,1.),(1.,0.)] - - result_ = assert_equals(expected_output, captured_output) - end function - - function check_new_line_separated_integers() result(result_) - type(result_t) result_ - - character(len=*), parameter :: expected_output = ( "0" // new_line("") // "1" //new_line("") // "2") - character(len=len(expected_output)) captured_output - - write(captured_output, fmt = separated_values(separator=new_line(""), mold=[integer::])) [0,1,2] - - result_ = assert_equals(captured_output, "0" // new_line("") // "1" //new_line("") // "2") - end function - - function check_cssv_character() result(result_) - type(result_t) result_ - - integer, parameter :: num_spaces=3 - character(len=*), parameter :: expected_output = "Yodel, Ay, Hee, Hoo!" - character(len=len(expected_output)+num_spaces) captured_output - - write(captured_output, fmt = separated_values(separator=", ", mold=[integer::])) "Yodel", "Ay", "Hee", "Hoo!" - - result_ = assert_equals(expected_output, captured_output) - end function - -end module formats_test diff --git a/tests/main.f90 b/tests/main.f90 deleted file mode 100644 index 3262ac5a..00000000 --- a/tests/main.f90 +++ /dev/null @@ -1,29 +0,0 @@ -! Generated by make_vegetable_driver. DO NOT EDIT -program main - implicit none - - call run() -contains - subroutine run() - use data_partition_test, only: & - data_partition_data_partition => test_data_partition - use formats_test, only: & - formats_object => test_object - use object_m_test, only: & - object_m_object => test_object - use user_defined_collectives_test, only: & - user_defined_collectives_co_all => test_co_all - use vegetables, only: test_item_t, test_that, run_tests - - type(test_item_t) :: tests - type(test_item_t) :: individual_tests(4) - - individual_tests(1) = data_partition_data_partition() - individual_tests(2) = formats_object() - individual_tests(3) = object_m_object() - individual_tests(4) = user_defined_collectives_co_all() - tests = test_that(individual_tests) - - call run_tests(tests) - end subroutine -end program diff --git a/tests/object_interface_test.f90 b/tests/object_interface_test.f90 deleted file mode 100644 index 653b2e69..00000000 --- a/tests/object_interface_test.f90 +++ /dev/null @@ -1,77 +0,0 @@ -module object_m_test - !! author: Damian Rouson - !! - !! summary: verify object pattern asbtract parent - use vegetables, only: & - result_t, input_t, integer_input_t, test_item_t, & ! types - describe, it, assert_equals, assert_that, assert_not ! functions - use object_m, only : object_t - implicit none - - private - public :: test_object - - type, extends(object_t) :: subject - contains - procedure write_formatted - end type - -contains - - function test_object() result(tests) - type(test_item_t) tests - - tests = describe( & - "object class", & - [it( & - ".not. user_defined() if only default-initialized", & - check_default_initialization), & - it( & - "user_defined() after call mark_as_defined", & - check_mark_as_defined)]) - end function - - function check_default_initialization() result(result_) - !! Verify that user_defined() is .false. for a default-initialied object - class(object_t), allocatable :: object - type(result_t) result_ - - allocate(subject :: object) - - result_ = assert_not(object%user_defined()) - end function - - function check_mark_as_defined() result(result_) - !! Verify that mark_as_defined results in user_defined() being .true. - class(object_t), allocatable :: object - type(result_t) result_ - - allocate(subject :: object) - - call object%mark_as_defined - result_ = assert_that(object%user_defined()) - end function - - subroutine write_formatted(self, unit, iotype, v_list, iostat, iomsg) - class(subject), intent(in) :: self - integer, intent(in) :: unit - character(*), intent(in) :: iotype - integer, intent(in) :: v_list(:) - integer, intent(out) :: iostat - character(*), intent(inout) :: iomsg - - select case(iotype) - case('LISTDIRECTED') - write(unit,*) self%user_defined() - iostat = 0 - iomsg = "" - case default - iostat = -1 - iomsg = "object_m_test: subject%write_formatted iotype received unsupported iotype " // iotype - end select - - associate( unused => v_list) - end associate - end subroutine - -end module object_m_test diff --git a/tests/user_defined_collectives_test.f90 b/tests/user_defined_collectives_test.f90 deleted file mode 100644 index 975adf5d..00000000 --- a/tests/user_defined_collectives_test.f90 +++ /dev/null @@ -1,43 +0,0 @@ -module user_defined_collectives_test - use Vegetables, only: Result_t, Test_Item_t, describe, it, assert_equals, assert_that, assert_not - use user_defined_collectives_m, only : co_all - implicit none - - private - public :: test_co_all - -contains - - function test_co_all() result(tests) - type(Test_Item_t) :: tests - - tests = describe( & - "co_all", & - [it( & - "sets all arguments to .true. when previously .true. on all images", & - check_co_all_with_all_true), & - it( & - "sets all arguments to .false. when previously .false. on image 1", & - check_co_all_with_one_false)]) - end function - - function check_co_all_with_all_true() result(result_) - type(Result_t) :: result_ - logical all_true - - all_true=.true. - - call co_all(all_true) - result_ = assert_that(all_true, "co_all argument remains .true. after call with all arguments .true.") - end function - - function check_co_all_with_one_false() result(result_) - type(Result_t) :: result_ - logical all_true - - all_true = merge(.false., .true., this_image()==1) - call co_all(all_true) - result_ = assert_not(all_true, "co_all argument is .false. after call with one argument .false.") - end function - -end module user_defined_collectives_test