44! The index arrays are of all INT_KINDS_TYPES
55
66
7- program test_selection
7+ module test_selection
88
9- use stdlib_error, only: check
109 use stdlib_kinds
1110 use stdlib_selection, only: select, arg_select
11+ use testdrive, only: new_unittest, unittest_type, error_type, check
12+
1213 implicit none
1314
14- #:for arraykind, arraytype in ARRAY_KINDS_TYPES
15- #:for intkind, inttype in INT_KINDS_TYPES
16- #:set name = rname("test_select", 1, arraytype, arraykind, intkind)
17- call ${name}$()
18- #:endfor
19- #:endfor
15+ private
16+ public :: collect_selection
2017
21- #:for arraykind, arraytype in ARRAY_KINDS_TYPES
22- #:for intkind, inttype in INT_KINDS_TYPES
23- #:set name = rname("test_arg_select", 1, arraytype, arraykind, intkind)
24- call ${name}$()
25- #:endfor
26- #:endfor
2718contains
2819
20+ !> Collect all exported unit tests
21+ subroutine collect_selection(testsuite)
22+ !> Collection of tests
23+ type(unittest_type), allocatable, intent(out) :: testsuite(:)
24+
25+ testsuite = [ &
26+ new_unittest("test_select_1_iint8_int8", test_select_1_iint8_int8) &
27+ #:for arraykind, arraytype in ARRAY_KINDS_TYPES
28+ #:for intkind, inttype in INT_KINDS_TYPES
29+ #:set name = rname("test_select", 1, arraytype, arraykind, intkind)
30+ , new_unittest("${name}$", ${name}$) &
31+ #:endfor
32+ #:endfor
33+
34+ #:for arraykind, arraytype in ARRAY_KINDS_TYPES
35+ #:for intkind, inttype in INT_KINDS_TYPES
36+ #:set name = rname("test_arg_select", 1, arraytype, arraykind, intkind)
37+ , new_unittest("${name}$", ${name}$) &
38+ #:endfor
39+ #:endfor
40+ ]
41+
42+ end subroutine collect_selection
43+
2944 #:for arraykind, arraytype in ARRAY_KINDS_TYPES
3045 #:for intkind, inttype in INT_KINDS_TYPES
3146 #:set name = rname("test_select", 1, arraytype, arraykind, intkind)
32- subroutine ${name}$()
47+ subroutine ${name}$(error)
48+ type(error_type), allocatable, intent(out) :: error
3349
3450 ${inttype}$, parameter :: N = 10, Nreps = 2, Nm = 8
3551 ${inttype}$, parameter :: Nr = min(HUGE(N)/2_int64, 25_int64) ! < HUGE(N)
@@ -50,64 +66,78 @@ contains
5066 do i = 1, size(x, kind=ip)
5167 x_copy = x
5268 call select(x_copy, i, kth_smallest)
53- call check( (kth_smallest == i**2), " ${name}$: kth smallest entry should be i**2")
69+ call check( error, (kth_smallest == i**2), " ${name}$: kth smallest entry should be i**2")
70+ if(allocated(error)) return
5471 end do
5572
5673 ! Check that it works when we specify "left" and know that the array
5774 ! is partially sorted due to previous calls to quickselect
5875 x_copy = x
5976 do i = 1, size(x, kind=ip), 1
6077 call select(x_copy, i, kth_smallest, left=i)
61- call check( (kth_smallest == i**2), " ${name}$: kth smallest entry with left specified")
78+ call check( error, (kth_smallest == i**2), " ${name}$: kth smallest entry with left specified")
79+ if(allocated(error)) return
6280 end do
6381
6482 ! Check that it works when we specify "right" and know that the array
6583 ! is partially sorted due to previous calls to quickselect
6684 x_copy = x
6785 do i = size(x, kind=ip), 1, -1
6886 call select(x_copy, i, kth_smallest, right=i)
69- call check( (kth_smallest == i**2), " ${name}$: kth smallest entry with right specified")
87+ call check( error, (kth_smallest == i**2), " ${name}$: kth smallest entry with right specified")
88+ if(allocated(error)) return
7089 end do
7190
7291 ! Simple tests
7392 mat = one * [3, 2, 7, 4, 5, 1, 4, -1]
7493 mat_copy = mat
7594 call select(mat_copy, 1_ip, kth_smallest)
76- call check( kth_smallest == -1, " ${name}$: mat test 1")
95+ call check(error, kth_smallest == -1, " ${name}$: mat test 1")
96+ if(allocated(error)) return
7797 mat_copy = mat
7898 call select(mat_copy, 2_ip, kth_smallest)
79- call check( kth_smallest == 1, " ${name}$: mat test 2")
99+ call check(error, kth_smallest == 1, " ${name}$: mat test 2")
100+ if(allocated(error)) return
80101 mat_copy = mat
81102 call select(mat_copy, size(mat, kind=ip)+1_ip-4_ip, kth_smallest)
82- call check( kth_smallest == 4, " ${name}$: mat test 3")
103+ call check(error, kth_smallest == 4, " ${name}$: mat test 3")
104+ if(allocated(error)) return
83105 mat_copy = mat
84106 call select(mat_copy, 5_ip, kth_smallest)
85- call check( kth_smallest == 4, " ${name}$: mat test 4")
107+ call check(error, kth_smallest == 4, " ${name}$: mat test 4")
108+ if(allocated(error)) return
86109 mat_copy = mat
87110 call select(mat_copy, 6_ip, kth_smallest)
88- call check( kth_smallest == 4, " ${name}$: mat test 5")
111+ call check(error, kth_smallest == 4, " ${name}$: mat test 5")
112+ if(allocated(error)) return
89113 mat_copy = mat
90114 call select(mat_copy, 7_ip, kth_smallest)
91- call check( kth_smallest == 5, " ${name}$: mat test 6")
115+ call check(error, kth_smallest == 5, " ${name}$: mat test 6")
116+ if(allocated(error)) return
92117
93118 ! Check it works for size(a) == 1
94119 len1(1) = -1 * one
95120 call select(len1, 1_ip, kth_smallest)
96- call check(kth_smallest == -1, " ${name}$: array with size 1")
121+ call check(error, kth_smallest == -1, " ${name}$: array with size 1")
122+ if(allocated(error)) return
97123
98124 ! Check it works for size(a) == 2
99125 len2 = [-3, -5]*one
100126 call select(len2, 2_ip, kth_smallest)
101- call check(kth_smallest == -3, " ${name}$: array with size 2, test 1")
127+ call check(error, kth_smallest == -3, " ${name}$: array with size 2, test 1")
128+ if(allocated(error)) return
102129 len2 = [-3, -5]*one
103130 call select(len2, 1_ip, kth_smallest)
104- call check(kth_smallest == -5, " ${name}$: array with size 2, test 2")
131+ call check(error, kth_smallest == -5, " ${name}$: array with size 2, test 2")
132+ if(allocated(error)) return
105133 len2 = [-1, -1]*one
106134 call select(len2, 1_ip, kth_smallest)
107- call check(kth_smallest == -1, " ${name}$: array with size 2, test 3")
135+ call check(error, kth_smallest == -1, " ${name}$: array with size 2, test 3")
136+ if(allocated(error)) return
108137 len2 = [-1, -1]*one
109138 call select(len2, 2_ip, kth_smallest)
110- call check(kth_smallest == -1, " ${name}$: array with size 2, test 4")
139+ call check(error, kth_smallest == -1, " ${name}$: array with size 2, test 4")
140+ if(allocated(error)) return
111141
112142 !
113143 ! Test using random data
@@ -174,7 +204,8 @@ contains
174204 end do
175205 end do
176206
177- call check( (.not. any_failed), " ${name}$: random number test failed ")
207+ call check(error, (.not. any_failed), " ${name}$: random number test failed ")
208+ if(allocated(error)) return
178209
179210
180211 end subroutine
@@ -185,7 +216,8 @@ contains
185216 #:for arraykind, arraytype in ARRAY_KINDS_TYPES
186217 #:for intkind, inttype in INT_KINDS_TYPES
187218 #:set name = rname("test_arg_select", 1, arraytype, arraykind, intkind)
188- subroutine ${name}$
219+ subroutine ${name}$(error)
220+ type(error_type), allocatable, intent(out) :: error
189221
190222 ${inttype}$, parameter :: N = 10, Nreps = 2, Nm = 8
191223 ${inttype}$, parameter :: Nr = min(HUGE(N)/2_int64, 25_int64) ! < HUGE(N)
@@ -210,23 +242,26 @@ contains
210242 do i = 1, size(x, kind=ip)
211243 indx_copy = indx
212244 call arg_select(x, indx, i, kth_smallest)
213- call check(x(kth_smallest) == i**2, " ${name}$: kth smallest entry should be i**2")
245+ call check(error, x(kth_smallest) == i**2, " ${name}$: kth smallest entry should be i**2")
246+ if(allocated(error)) return
214247 end do
215248
216249 ! Check that it works when we specify "left" and know that the index
217250 ! array is partially sorted due to previous calls to arg_select
218251 indx_copy = indx
219252 do i = 1, size(x, kind=ip), 1
220253 call arg_select(x, indx_copy, i, kth_smallest, left=i)
221- call check( (x(kth_smallest) == i**2), " ${name}$: kth smallest entry with left specified")
254+ call check(error, (x(kth_smallest) == i**2), " ${name}$: kth smallest entry with left specified")
255+ if(allocated(error)) return
222256 end do
223257
224258 ! Check that it works when we specify "right" and know that the index
225259 ! array is partially sorted due to previous calls to arg_select
226260 indx_copy = indx
227261 do i = size(x, kind=ip), 1, -1
228262 call arg_select(x, indx_copy, i, kth_smallest, right=i)
229- call check( (x(kth_smallest) == i**2), " ${name}$: kth smallest entry with right specified")
263+ call check(error, (x(kth_smallest) == i**2), " ${name}$: kth smallest entry with right specified")
264+ if(allocated(error)) return
230265 end do
231266
232267 ! Simple tests
@@ -235,55 +270,66 @@ contains
235270
236271 indx_mat_copy = indx_mat
237272 call arg_select(mat, indx_mat_copy, 1_ip, kth_smallest)
238- call check( mat(kth_smallest) == -1, " ${name}$: mat test 1")
273+ call check(error, mat(kth_smallest) == -1, " ${name}$: mat test 1")
274+ if(allocated(error)) return
239275
240276 indx_mat_copy = indx_mat
241277 call arg_select(mat, indx_mat_copy, 2_ip, kth_smallest)
242- call check( mat(kth_smallest) == 1, " ${name}$: mat test 2")
278+ call check(error, mat(kth_smallest) == 1, " ${name}$: mat test 2")
279+ if(allocated(error)) return
243280
244281 indx_mat_copy = indx_mat
245282 call arg_select(mat, indx_mat_copy, size(mat, kind=ip)+1_ip-4_ip, &
246283 kth_smallest)
247- call check( mat(kth_smallest) == 4, " ${name}$: mat test 3")
284+ call check(error, mat(kth_smallest) == 4, " ${name}$: mat test 3")
285+ if(allocated(error)) return
248286
249287 indx_mat_copy = indx_mat
250288 call arg_select(mat, indx_mat_copy, 5_ip, kth_smallest)
251- call check( mat(kth_smallest) == 4, " ${name}$: mat test 4")
289+ call check(error, mat(kth_smallest) == 4, " ${name}$: mat test 4")
290+ if(allocated(error)) return
252291
253292 indx_mat_copy = indx_mat
254293 call arg_select(mat, indx_mat_copy, 6_ip, kth_smallest)
255- call check( mat(kth_smallest) == 4, " ${name}$: mat test 5")
294+ call check(error, mat(kth_smallest) == 4, " ${name}$: mat test 5")
295+ if(allocated(error)) return
256296
257297 indx_mat_copy = indx_mat
258298 call arg_select(mat, indx_mat_copy, 7_ip, kth_smallest)
259- call check( mat(kth_smallest) == 5, " ${name}$: mat test 6")
299+ call check(error, mat(kth_smallest) == 5, " ${name}$: mat test 6")
300+ if(allocated(error)) return
260301
261302 ! Check it works for size(a) == 1
262303 len1(1) = -1 * one
263304 indx_len1(1) = 1
264305 call arg_select(len1, indx_len1, 1_ip, kth_smallest)
265- call check(len1(kth_smallest) == -1, " ${name}$: array with size 1")
306+ call check(error, len1(kth_smallest) == -1, " ${name}$: array with size 1")
307+ if(allocated(error)) return
266308
267309 ! Check it works for size(a) == 2
268310 len2 = [-3, -5] * one
269311 indx_len2 = [1_ip, 2_ip]
270312 call arg_select(len2, indx_len2, 2_ip, kth_smallest)
271- call check(len2(kth_smallest) == -3, " ${name}$: array with size 2, test 1")
313+ call check(error, len2(kth_smallest) == -3, " ${name}$: array with size 2, test 1")
314+ if(allocated(error)) return
272315
273316 len2 = [-3, -5] * one
274317 indx_len2 = [1_ip, 2_ip]
275318 call arg_select(len2, indx_len2, 1_ip, kth_smallest)
276- call check(len2(kth_smallest) == -5, " ${name}$: array with size 2, test 2")
319+ call check(error, len2(kth_smallest) == -5, " ${name}$: array with size 2, test 2")
320+ if(allocated(error)) return
277321
278322 len2 = [-1, -1] * one
279323 indx_len2 = [1_ip, 2_ip]
280324 call arg_select(len2, indx_len2, 1_ip, kth_smallest)
281- call check(len2(kth_smallest) == -1, " ${name}$: array with size 2, test 3")
325+ call check(error, len2(kth_smallest) == -1, " ${name}$: array with size 2, test 3")
326+ if(allocated(error)) return
282327
283328 len2 = [-1, -1] * one
284329 indx_len2 = [1_ip, 2_ip]
285330 call arg_select(len2, indx_len2, 2_ip, kth_smallest)
286- call check(len2(kth_smallest) == -1, " ${name}$: array with size 2, test 4")
331+ call check(error, len2(kth_smallest) == -1, " ${name}$: array with size 2, test 4")
332+ if(allocated(error)) return
287333
288334 !
289335 ! Test using random data
@@ -360,10 +406,39 @@ contains
360406 end do
361407 end do
362408
363- call check( (.not. any_failed), " ${name}$: random number test failed ")
409+ call check(error, (.not. any_failed), " ${name}$: random number test failed ")
410+ if(allocated(error)) return
364411
365412 end subroutine
366413 #:endfor
367414 #:endfor
368415
369- end program
416+ end module
417+
418+ program tester
419+ use, intrinsic :: iso_fortran_env, only: compiler_version, error_unit
420+ use testdrive, only: new_testsuite, run_testsuite, testsuite_type
421+ use test_selection, only: collect_selection
422+
423+ implicit none
424+ integer :: stat, is
425+ type(testsuite_type), allocatable :: testsuites(:)
426+ character(len=*), parameter :: fmt = '("#", *(1x, a))'
427+
428+ stat = 0
429+
430+ testsuites = [ &
431+ new_testsuite("selection", collect_selection) &
432+ ]
433+
434+ do is = 1, size(testsuites)
435+ write(error_unit, fmt) "Testing:", testsuites(is)%name
436+ call run_testsuite(testsuites(is)%collect, error_unit, stat)
437+ end do
438+
439+ if (stat > 0) then
440+ write(error_unit, '(i0, 1x, a)') stat, "test(s) failed!"
441+ error stop
442+ end if
443+
444+ end program tester
0 commit comments