{"id":22625506,"url":"https://github.com/thomasms/toast","last_synced_at":"2026-01-07T09:15:18.203Z","repository":{"id":44454157,"uuid":"130755503","full_name":"thomasms/toast","owner":"thomasms","description":"Testing Or ASsertion Toolkit - Fortran unit testing library","archived":false,"fork":false,"pushed_at":"2021-03-22T19:51:42.000Z","size":65,"stargazers_count":7,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T13:22:58.413Z","etag":null,"topics":["fortran","fruit","pfunit","testcase","testing","toast","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Fortran","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-23T20:54:09.000Z","updated_at":"2024-11-24T18:04:56.000Z","dependencies_parsed_at":"2022-09-22T08:43:13.008Z","dependency_job_id":null,"html_url":"https://github.com/thomasms/toast","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasms%2Ftoast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasms%2Ftoast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasms%2Ftoast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasms%2Ftoast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasms","download_url":"https://codeload.github.com/thomasms/toast/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246133660,"owners_count":20728740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fortran","fruit","pfunit","testcase","testing","toast","unit-testing"],"created_at":"2024-12-09T00:25:59.317Z","updated_at":"2026-01-07T09:15:18.161Z","avatar_url":"https://github.com/thomasms.png","language":"Fortran","readme":"## TOAST -Testing Or ASsertion Toolkit\n\n[![Build Status](https://travis-ci.org/thomasms/toast.svg?branch=master)](https://travis-ci.org/thomasms/toast)\n\nA much needed library for Fortran.\n\nYes I know that pFUnit and FRUIT exist however:\n- pFUnit maybe great but it is too complex and messy to use\n- FRUIT is much simpler but a bit limited and not maintained\n\nHence the need for Toast!\n\n### Status:\nStill very early, API likely to change.\n- [x] Basic Test type\n- [x] Support Int, Real and logical assert\n- [x] Support for comparing character arrays\n- [ ] Support Complex assert\n- [x] Tolerances (absolute + relative) for real\n- [x] Setup CI\n- [ ] Testing needs testing\n- [ ] Support for derived data types\n- [ ] Support for arrays\n- [ ] Support for mpi\n- [ ] Ensure threadsafety\n- [x] JSON output\n- [ ] File comparision\n- [ ] Regression testing framework\n\n\nToast can be used in 2 main ways:\n1. Using the base TestCase for assertions only and a summary. It's very simple to use but limited\n2. Extend the base TestCase to implement the run subroutine and make use of TestSuites. This works similar to Python unit testing framework.\n\nA simple example of type 1 usage is given in the example below:\n\n```fortran\nprogram example\n    use toast     !\u003c testing library\n    implicit none\n\n    type(TestCase) :: test\n\n    call test%assertequal(3_ki4, 5_ki4)\n    call test%assertequal(3_ki4, 3_ki4)\n\n    call test%assertequal(3.0_kr8, 3.0_kr8)\n    call test%assertequal(3.0_kr16, 3.0_kr16)\n\n    call test%assertequal(3.0_kr4, 3.1_kr4, abs_tol=0.099_kr4)\n    call test%assertequal(3.0_kr4, 3.1_kr4, abs_tol=0.1_kr4)\n    \n    call printsummary(test)\n\nend program example\n```\n\nThis will output:\n```bash\nexample1 - FAILURE\n[Passed assertions:     16 /     19 ] ++++++++++++++++\n[Failed assertions:      3 /     19 ] ---\n\n Failure @ 3 does not equal 5\n Failure @ arrays should not match\n Failure @ 3 should not equal 3.1 with low tolerance\n\nexample1 - FAILURE\n[Passed assertions:      4 /      6 ] ++++\n[Failed assertions:      2 /      6 ] --\n\n Failure @ False should not be true.\n Failure @ Assert strings are not equal\n\n1\n```\n\nA simple example of type 2 usage is given in the example below:\n\n```fortran\n!\u003e Define tests here\nmodule exampletestcases\n    use toast     !\u003c testing library\n    implicit none\n    private\n\n    !\u003e We define the test case here\n    type, extends(TestCase), public :: PassingTestCaseExample\n    contains\n        procedure :: test =\u003e PassingTestCaseExampleProc\n    end type PassingTestCaseExample\n\n!\u003e Alternatively, we can define a test case using the include macro\n#define MACRO_TESTCASE_NAME FailingTestCaseExample\n#define MACRO_TESTCASE_NAME_PROC FailingTestCaseExampleProc\n#include \"definetestcase.h\"\n\n#define MACRO_TESTCASE_NAME PassAgainTestCaseExample\n#define MACRO_TESTCASE_NAME_PROC PassAgainTestCaseExampleProc\n#include \"definetestcase.h\"\n\n#define MACRO_TESTCASE_NAME FailAgainTestCaseExample\n#define MACRO_TESTCASE_NAME_PROC FailAgainTestCaseExampleProc\n#include \"definetestcase.h\"\n\ncontains\n\n    !\u003e passing test example\n    subroutine PassingTestCaseExampleProc(this)\n        class(PassingTestCaseExample), intent(inout) :: this\n\n        ! integer asserts\n        call this%assertequal(127_ki1, 127_ki1, message = \"127 should equal 127\")\n        call this%assertequal(32767_ki2, 32767_ki2, message = \"32767 should equal 32767\")\n        call this%assertequal(3.0_kr8, 3.0_kr8, message = \"3 should equal 3\")\n        call this%assertequal(3.0_kr4, 3.1_kr4, abs_tol=0.1_kr4, \u0026\n                             \u0026 message = \"3 should equal 3.1 with higher tolerance\")\n        call this%asserttrue(2_ki4*3_ki4 == 6_ki4, \"2*3 == 6 should be true.\")\n        call this%assertfalse(.false., \"False should be false.\")\n\n    end subroutine\n\n    !\u003e failing test example\n    subroutine FailingTestCaseExampleProc(this)\n        class(FailingTestCaseExample), intent(inout) :: this\n\n        ! integer asserts\n        call this%assertequal(127_ki1, 12_ki1, message = \"127 should equal 127\")\n        call this%assertequal(32767_ki2, 327_ki2, message = \"32767 should equal 32767\")\n        call this%assertequal(3.0_kr8, 3.4_kr8, message = \"3 should equal 3\")\n        call this%assertequal(3.0_kr4, 3.1_kr4, abs_tol=0.09_kr4, \u0026\n                             \u0026 message = \"3 should equal 3.1 with higher tolerance\")\n        call this%asserttrue(2_ki4*3_ki4 == 7_ki4, \"2*3 == 6 should be true.\")\n        call this%assertfalse(.true., \"False should be false.\")\n\n    end subroutine\n\n    !\u003e passing test example\n    subroutine PassAgainTestCaseExampleProc(this)\n        class(PassAgainTestCaseExample), intent(inout) :: this\n\n        call this%asserttrue(.not. .false., \"Not false should be true.\")\n\n    end subroutine\n\n    !\u003e failing test example\n    subroutine FailAgainTestCaseExampleProc(this)\n        class(FailAgainTestCaseExample), intent(inout) :: this\n\n        call this%asserttrue(.false., \"false cannot be true.\")\n\n    end subroutine\n\nend module exampletestcases\n\n!\u003e Main test program\nprogram example\n    use toast\n    use exampletestcases\n    implicit none\n\n    type(TestSuite) :: suite\n    suite = TestSuite(name=\"My test suite\")\n\n    ! add the tests here\n    call suite%append(PassingTestCaseExample(name=\"passing_case1\"))\n    call suite%append(FailingTestCaseExample(name=\"failing_case1\"))\n    call suite%append(PassAgainTestCaseExample(name=\"passing_case2\"))\n    call suite%append(FailAgainTestCaseExample(name=\"failing_case2\"))\n    call suite%append(PassingTestCaseExample(name=\"passing_case1_again\"))\n\n    call suite%runall()\n    \n    call printsummary(suite)\n\nend program example\n```\n\nThis will output:\n```bash\n[2136][tom@Unknown:~/Dev/toast/buildifort/bin]$ ./toastexample2\n                      -- test case results --\npassing_case1 - SUCCESS\n[Passed assertions:      6 /      6 ] ++++++\n[Failed assertions:      0 /      6 ] \n\n\nfailing_case1 - FAILURE\n[Passed assertions:      0 /      6 ] \n[Failed assertions:      6 /      6 ] ------\n\n Failure @ 127 should equal 127\n Failure @ 32767 should equal 32767\n Failure @ 3 should equal 3\n Failure @ 3 should equal 3.1 with higher tolerance\n Failure @ 2*3 == 6 should be true.\n Failure @ False should be false.\n\npassing_case2 - SUCCESS\n[Passed assertions:      3 /      3 ] +++\n[Failed assertions:      0 /      3 ] \n\n\nfailing_case2 - FAILURE\n[Passed assertions:      0 /      2 ] \n[Failed assertions:      2 /      2 ] --\n\n Failure @ false cannot be true.\n Failure @ arrays should not match\n\npassing_case1_again - SUCCESS\n[Passed assertions:      6 /      6 ] ++++++\n[Failed assertions:      0 /      6 ] \n\n\n              -------------------------------------\n                     -- TOAST test results --\n\n                          -- FAILURE --\n\n[Passed test cases:      3 /     5] (      15 /      23 asserts)\n[Failed test cases:      2 /     5] (       8 /      23 asserts)\n```\n\n\nDue to generic type bound procedures on the TestCase type, the compiler catches errors when trying to compare different types, for example, the following will not compile:\n\n```fortran\nprogram example\n    use toast     !\u003c testing library\n    implicit none\n    \n    type(TestCase) :: test\n\n    !\u003e Will not compile since kr16 and kr4 are different types\n    call test%assertequal(3.0_kr16, 3.0_kr4)\n    \n    call printsummary(test)\n\nend program example\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasms%2Ftoast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasms%2Ftoast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasms%2Ftoast/lists"}