Skip to content

Commit 8bae5de

Browse files
authored
Merge pull request #84 from BerkeleyLab/wrap-assert-assert
Add specific procedure for call_julienne_assert_ generic interface
2 parents 5fc0817 + 655e848 commit 8bae5de

27 files changed

Lines changed: 191 additions & 83 deletions

README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,33 @@ Getting Started
156156
---------------
157157
### Writing Assertions
158158
To write a Julienne assertion, insert a function-like preprocessor macro
159-
`call_julienne_assert` on a single line as in the following program:
159+
`call_julienne_assert` on a single line as in each of the two macro
160+
invocations below:
160161
```fortran
161162
#include "julienne-assertion-macros.h"
162163
program main
163164
use, julienne_m, only : call_julienne_assert_
164165
implicit none
165166
real, parameter :: x=1., y=2., tolerance=3.
166167
call_julienne_assert(x .approximates. y .within. tolerance)
168+
call_julienne_assert(abs(x-y) < tolerance)
167169
end program
168170
```
169-
where inserting `-DASSERTIONS` in a compile command will expand the macro to
171+
where inserting `-DASSERTIONS` in a compile command will expand the macros to
170172
```fortran
171-
call call_julienne_assert_(x .approximates. y .within. tolerance)
173+
call call_julienne_assert_(x .approximates. y .within. tolerance, __FILE__, __LINE__)
174+
call call_julienne_assert_(allocated(a), __FILE__, __LINE__)
172175
```
173-
and where dots (`.`) delimit Julienne operators and the parenthetical expression
174-
evaluates to a Julienne `test_diagnosis_t` object.
176+
and where dots (`.`) delimit Julienne operators. The above expression containing
177+
Julienne operators evaluates to a Julienne `test_diagnosis_t` object, whereas
178+
expression `allocated(a)` on the subsequent line evaluates to a `logical` value.
179+
If an assertion containing a Julienne expression fails, Julienne inserts diagnostic
180+
information into the stop code in an ultimate `error stop`. If an expression
181+
evaluates to a `logical` value of `false.`, the error stop code will contain a
182+
literal copy of the expression (e.g., `allocated(a)`). In either case, Julienne
183+
also inserts the file and line number into the stop code using via the `__FILE__`
184+
and `__LINE__` macros, respectively. Most compilers write the resulting stop code
185+
to `error_unit`.
175186

176187
### Writing Unit Tests
177188
Writing tests using Julienne involves constructing a test-description array,

fpm.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "julienne"
22

33
[dependencies]
4-
assert = {git = "https://github.com/berkeleylab/assert", tag = "3.0.0"}
4+
assert = {git = "https://github.com/berkeleylab/assert", tag = "3.0.2"}
55

66
[install]
77
library = true

src/julienne/julienne_assert_m.f90

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
2+
! Terms of use are as specified in LICENSE.txt
3+
4+
module julienne_assert_m
5+
!! Define interfaces for writing assertions
6+
use julienne_test_diagnosis_m, only : test_diagnosis_t
7+
implicit none
8+
9+
private
10+
public :: call_julienne_assert_
11+
public :: julienne_assert
12+
13+
interface call_julienne_assert_
14+
15+
pure module subroutine julienne_assert(test_diagnosis, file, line)
16+
!! This subroutine wraps the Assert library's `assert` subroutine.
17+
!!
18+
!! Use Cases
19+
!! ---------
20+
!! 1. Invoke julienne_assert via the generic interface `call_julienne_assert` to
21+
!! facilitate complete removal when compiling without the flag `-DASSERTIONS`.
22+
!! 2. Invoke julienne_assert via direct procedure call to guarantee execution.
23+
!!
24+
!! Usage
25+
!! -----
26+
!! Make the only actual argument an expression containing `test_diagnosis_t` defined
27+
!! operations, such as `x .approximates. y .within. tolerance`. The expression
28+
!! result will be a `test_diagnosis_t` object on which `julienne_assert` will invoke
29+
!! the `diagnostics_string()` type-bound procedure, the result of which julienne_assert
30+
!! will include in the stop code of an `error stop` if the expresssion is untrue.
31+
!! The resulting stop code will contain such information as the operand values and
32+
!! roles (expected value, actual value, tolerance value). In use case 1, compiling
33+
!! with `-DASSERTIONS` will cause the preprocessor to insert the corresponding
34+
!! invocations's line number and the encompassing file's name as the `file` and `line`
35+
!! arguments, respectively, which `julienne_assert` will include in the stop code.
36+
!! Most compilers will write the stop code to `error_unit`.
37+
!!
38+
!! If a literal reproduction of the test expression suffices, such as when the
39+
!! expression is `allocated(a)`, then instead invoke the Assert library's `assert`
40+
!! subroutine by that library's `call_assert` macro or by direct call.
41+
!! When invoking via the macro, make the only actual argument, `assertion`, a
42+
!! `logical` expression. Then if compiling with `-DASSERTIONS` and if the assertion
43+
!! evaluates to `.false.`, the stop code will include the text of the expression
44+
!! argument, the file name, and the line number of the `call_assert` macro invocation.
45+
implicit none
46+
type(test_diagnosis_t), intent(in) :: test_diagnosis
47+
character(len=*), intent(in), optional :: file
48+
integer, intent(in), optional :: line
49+
end subroutine
50+
51+
end interface
52+
53+
end module julienne_assert_m

src/julienne/julienne_assert_s.f90

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
2+
! Terms of use are as specified in LICENSE.txt
3+
4+
submodule(julienne_assert_m) julienne_assert_s
5+
use assert_m, only : assert_always
6+
use julienne_m, only : string_t
7+
implicit none
8+
9+
contains
10+
11+
module procedure julienne_assert
12+
character(len=:), allocatable :: diagnostics_string
13+
diagnostics_string = test_diagnosis%diagnostics_string()
14+
if (present(file)) diagnostics_string = diagnostics_string // " in file " // file
15+
if (present(line)) diagnostics_string = diagnostics_string // " at line " // string_t(line)
16+
call assert_always(test_diagnosis%test_passed(), diagnostics_string)
17+
end procedure
18+
19+
end submodule julienne_assert_s

src/julienne/julienne_bin_s.F90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
22
! Terms of use are as specified in LICENSE.txt
33

4-
#include "assert_macros.h"
4+
#include "julienne-assert-macros.h"
55

66
submodule(julienne_bin_m) julienne_bin_s
7-
use assert_m
7+
use julienne_m, only : call_julienne_assert_, operator(.isAtLeast.)
88
implicit none
99

1010
contains
1111

1212
module procedure construct
1313

14-
call_assert(num_items>=num_bins)
14+
call_julienne_assert(num_items .isAtLeast. num_bins)
1515

1616
associate( remainder => mod(num_items, num_bins), items_per_bin => num_items/num_bins)
1717

src/julienne/julienne_command_line_m.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
22
! Terms of use are as specified in LICENSE.txt
3+
34
module julienne_command_line_m
45
!! return command line argument information
56
implicit none

src/julienne/julienne_command_line_s.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
22
! Terms of use are as specified in LICENSE.txt
3+
34
submodule(julienne_command_line_m) julienne_command_line_s
45
implicit none
56

src/julienne/julienne_file_m.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
22
! Terms of use are as specified in LICENSE.txt
3+
34
module julienne_file_m
45
!! A representation of a file as an object
56
use julienne_string_m, only : string_t

src/julienne/julienne_formats_m.F90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
22
! Terms of use are as specified in LICENSE.txt
3+
34
module julienne_formats_m
45
!! Useful strings for formatting `print` and `write` statements
56
implicit none

src/julienne/julienne_formats_s.F90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
! Copyright (c) 2024-2025, The Regents of the University of California and Sourcery Institute
22
! Terms of use are as specified in LICENSE.txt
3+
34
submodule(julienne_formats_m) julienne_formats_s
45
!! Construct separated-value formats
56
implicit none

0 commit comments

Comments
 (0)