Skip to content

Commit 348af01

Browse files
committed
refac(test_descrip): elemental test_result factory
1 parent f0adce5 commit 348af01

File tree

6 files changed

+153
-55
lines changed

6 files changed

+153
-55
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
module sourcery_test_description_m
2+
!! Define an abstraction for describing test intentions and test functions
3+
use sourcery_string_m, only : string_t
4+
use sourcery_test_result_m, only : test_result_t
5+
implicit none
6+
7+
private
8+
public :: test_description_t
9+
#ifdef __GFORTRAN__
10+
public :: test_function_i
11+
#endif
12+
13+
abstract interface
14+
function test_function_i() result(passes)
15+
implicit none
16+
logical passes
17+
end function
18+
end interface
19+
20+
type test_description_t
21+
!! Encapsulate test descriptions and test-functions
22+
private
23+
type(string_t) description_
24+
procedure(test_function_i), pointer, nopass :: test_function_ => null()
25+
contains
26+
procedure run
27+
end type
28+
29+
interface test_description_t
30+
31+
module function construct(description, test_function) result(test_description)
32+
!! The result is a test_description_t object with the components defined by the dummy arguments
33+
implicit none
34+
type(string_t), intent(in) :: description
35+
procedure(test_function_i), intent(in), pointer :: test_function
36+
type(test_description_t) test_description
37+
end function
38+
39+
end interface
40+
41+
interface
42+
43+
impure elemental module function run(self) result(test_result)
44+
!! The result encapsulates the test description and test outcome
45+
implicit none
46+
class(test_description_t), intent(in) :: self
47+
type(test_result_t) test_result
48+
end function
49+
50+
end interface
51+
52+
end module sourcery_test_description_m
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
submodule(sourcery_test_description_m) sourcery_test_description_s
2+
implicit none
3+
4+
contains
5+
6+
module procedure construct
7+
test_description%description_ = description
8+
test_description%test_function_ => test_function
9+
end procedure
10+
11+
module procedure run
12+
test_result = test_result_t(self%description_, self%test_function_())
13+
end procedure
14+
15+
end submodule sourcery_test_description_s

src/sourcery/sourcery_test_result_m.f90

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,22 @@ module sourcery_test_result_m
1818

1919
interface test_result_t
2020

21-
elemental module function construct(description, passed) result(test_result)
21+
elemental module function construct_from_character(description, passed) result(test_result)
2222
!! The result is a test_result_t object with the components defined by the dummy arguments
2323
implicit none
2424
character(len=*), intent(in) :: description
2525
logical, intent(in) :: passed
2626
type(test_result_t) test_result
2727
end function
2828

29+
module function construct_from_string(description, passed) result(test_result)
30+
!! The result is a test_result_t object with the components defined by the dummy arguments
31+
implicit none
32+
type(string_t), intent(in) :: description
33+
logical, intent(in) :: passed
34+
type(test_result_t) test_result
35+
end function
36+
2937
end interface
3038

3139
interface

src/sourcery/sourcery_test_result_s.f90

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
contains
66

7-
module procedure construct
7+
module procedure construct_from_character
8+
test_result%description_ = description
9+
test_result%passed_ = passed
10+
end procedure
11+
12+
module procedure construct_from_string
813
test_result%description_ = description
914
test_result%passed_ = passed
1015
end procedure

test/test_result_test.F90

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module test_result_test_m
2+
!! Verify test_result_t object behavior
3+
use sourcery_string_m, only : string_t
4+
use sourcery_test_m, only : test_t, test_result_t
5+
use sourcery_test_description_m, only : test_description_t
6+
#ifdef __GFORTRAN__
7+
use sourcery_test_description_m, only : test_function_i
8+
#endif
9+
implicit none
10+
11+
private
12+
public :: test_result_test_t
13+
14+
type, extends(test_t) :: test_result_test_t
15+
contains
16+
procedure, nopass :: subject
17+
procedure, nopass :: results
18+
end type
19+
20+
contains
21+
22+
pure function subject() result(specimen)
23+
character(len=:), allocatable :: specimen
24+
specimen = "The test_result_t type"
25+
end function
26+
27+
function results() result(test_results)
28+
type(test_result_t), allocatable :: test_results(:)
29+
type(test_description_t), allocatable :: test_descriptions(:)
30+
#ifndef __GFORTRAN__
31+
test_descriptions = [ &
32+
test_description_t(string_t("constructing an array of test_result_t objects elementally"), check_array_result_construction) &
33+
test_description_t(string_t("reporting failure if the test fails on one image"), check_single_image_failure) &
34+
]
35+
#else
36+
! Work around missing Fortran 2008 feature: associating a procedure actual argument with a procedure pointer dummy argument:
37+
procedure(test_function_i), pointer :: check_array_ptr, check_single_ptr
38+
39+
check_array_ptr => check_array_result_construction
40+
check_single_ptr => check_single_image_failure
41+
42+
test_descriptions = [ &
43+
test_description_t(string_t("constructing an array of test_result_t objects elementally"), check_array_ptr), &
44+
test_description_t(string_t("reporting failure if the test fails on one image"), check_single_ptr) &
45+
]
46+
#endif
47+
test_results = test_descriptions%run()
48+
end function
49+
50+
function check_array_result_construction() result(passed)
51+
type(test_result_t), allocatable :: test_results(:)
52+
logical passed
53+
54+
test_results = test_result_t(["foo","bar"], [.true.,.false.])
55+
passed = size(test_results)==2
56+
end function
57+
58+
function check_single_image_failure() result(passed)
59+
type(test_result_t), allocatable :: test_result
60+
logical passed
61+
62+
if (this_image()==1) then
63+
test_result = test_result_t("image 1 fails", .false.)
64+
else
65+
test_result = test_result_t("all images other than 1 pass", .true.)
66+
end if
67+
68+
passed = .not. test_result%passed()
69+
end function
70+
71+
end module test_result_test_m

test/test_result_test.f90

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)