Skip to content

Proposal for test_condition #121

Closed
Closed
@milancurcic

Description

@milancurcic

Evolved from discussion in #116.

Summary

This is a proposal to add a subroutine test_condition to stdlib_experimental_error that will:

  • Test the value of a logical condition like assert in stdlib_experimental_error does;
  • Allow printing a custom error message to stderr;
  • Optionally, allow passing an exit code like with assert;
  • Optionally, only print the message without stopping the program, i.e. warn only;

This is useful for testing both programmer and user errors. It can be used regardless of how the program is built (debug or release mode).

It could also be used as a basic building block toward higher-level testing or exception handling proposed in #95.

Description

test_condition tests an input logical condition. If the condition evaluates to .false., the default behavior is to stop the program and print the error message. Optionally, the user can pass an exit code to stop the program with. Optionally, the user can choose to not stop the program, but only print the warning.

API

subroutine test_condition(condition, msg, code, warn)
  logical, intent(in) :: condition
  character(*), intent(in), optional :: msg
  integer, intent(in), optional :: code
  logical, intent(in), optional :: warn

Arguments

  • condition: Logical condition to test
  • msg: (optional) Character string to print to stderr. Default
  • code: (optional) Integer exit code to set when stopping the program. (what should be the default value? Current implementation of assert doesn't set any default code as far as I can tell.)
  • warn: (optional) Logical. If .false. (default), test_condition will stop the program if condition is also false. If .true., it will print the error message to the screen and resume.

Example

use stdlib_experimental_error, only: test_condition
...
call test_condition(n > 0, 'n > 0 failed', warn=.true.)

Implementation

subroutine test_condition(condition, msg, code, warn)
  logical, intent(in) :: condition
  character(*), intent(in), optional :: msg
  integer, intent(in), optional :: code
  logical, intent(in), optional :: warn
  if (.not. condition) then
    if (optval(warn, .false.)) then
      write(srderr,*) optval(msg, "Test failed.")
    else
      call error_stop(optval(msg, "Test failed."), code)
    end if
  end if
end subroutine test_condition

This implementation depends on optval and error_stop.

Requesting feedback from @certik @nncarlson @zbeekman @jvdp1 @ivan-pi.

For anybody reading, please explicitly thumbs up or down, and write a comment if thumbs down. This way we can get a clear idea on whether this is supported or not and how much.

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIDiscussion on a specific API for a proposal (exploratory)topic: utilitiescontainers, strings, files, OS/environment integration, unit testing, assertions, logging, ...

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions