{"id":22473197,"url":"https://github.com/bas080/bash-tap","last_synced_at":"2025-10-28T06:03:48.042Z","repository":{"id":147293174,"uuid":"244176321","full_name":"bas080/bash-tap","owner":"bas080","description":"Minimal tap utilities for (ba)sh scripts.","archived":false,"fork":false,"pushed_at":"2021-11-19T01:37:31.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-23T15:28:06.574Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bas080.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-01T15:43:41.000Z","updated_at":"2021-11-19T01:37:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"1ac06e0c-6e62-4d5d-b66a-d22c76b4a334","html_url":"https://github.com/bas080/bash-tap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bas080/bash-tap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bas080%2Fbash-tap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bas080%2Fbash-tap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bas080%2Fbash-tap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bas080%2Fbash-tap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bas080","download_url":"https://codeload.github.com/bas080/bash-tap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bas080%2Fbash-tap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281391783,"owners_count":26492903,"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","status":"online","status_checked_at":"2025-10-28T02:00:06.022Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-12-06T12:20:02.381Z","updated_at":"2025-10-28T06:03:48.008Z","avatar_url":"https://github.com/bas080.png","language":"Shell","readme":"# Bash Tap\n\nMinimal tap utilities for (ba)sh scripts.\n\n## Usage\n\nsource bash-tap into your `bash` or `sh` script and use one or more of the\nfunctions provided.\n\nHere is an example of sourcing bash-tap. This approach will require you to have\nthe bash-tap file placed in one of the `$PATH` directories.\n\n```bash ./test source-using-path-variable.t\nsource bash-tap\n\nplan 1\nok \"Sourced using PATH variable.\"\n```\n```\n1..1\nok - Sourced using PATH variable.\n```\n\nYou can also define the absolute or relative path to the bash-tap file.\n\n```bash ./test source-using-relative-path.t\nsource ./bash-tap\n\nplan 1\nok \"Sourced using relative path.\"\n```\n```\n1..1\nok - Sourced using relative path.\n```\n\n## Examples\n\nBash tap is tested with its own testing utilities. These tests also function\nas examples on how to use bash tap.\n\nTAP tests are required to have a plan defined. Otherwise it is not considered\na valid test run. Here is an example of a test run with 0 assertions.\n\n### Plan\n\n```bash ./test plan.t\nplan 0\n```\n```\n1..0\n```\n\n### Ok\n\nThe ok function simply prints out an TAP ok line.\n\n```bash ./test ok.t\nplan 1\nok \"Is ok.\"\n```\n```\n1..1\nok - Is ok.\n```\n\n### Append Plan\n\nSometimes you don't know how many tests will be run. For those cases it is\npossible to have bash-tap append the plan to the TAP output after all\nassertions have been run.\n\n```bash ./test append-plan.t\nok \"First ok.\"\nok \"Second ok.\"\nok \"Third ok.\"\nplan\n```\n```\nok - First ok.\nok - Second ok.\nok - Third ok.\n1..3\n```\n\n### Todo\n\nWhile maintaining the test suite it might be nice to define a todo so you don't\nforget to test a certain case.\n\n```bash ./test todo.t\nplan 1\ntodo \"A todo.\"\n```\n```\n1..1\nnot ok - # TODO A todo.\n```\n\n### Not Ok\n\nThe `not_ok` function simply prints out not ok TAP line.\n\n```bash ./test not_ok.bash || true\nplan 1\nnot_ok \"Is not ok.\"\n```\n\nAlso notice that running the test file directly causes the process to exit with\na non zero code.\n\n```bash bash\n./t/not_ok.bash\necho $?\n```\n```\n1..1\nnot ok - Is not ok.\n1\n```\n\n### Success\n\nBecause we are using bash and working with exit codes, it is nice to have a few\nhelpers to make working with bash nicer.\n\n```bash ./test success.t\nplan 1\ntrue; success \"Previous command had a zero exit code.\"\n```\n```\n1..1\nok - Previous command had a zero exit code.\n```\n\n### Failure\n\n```bash ./test failure.t\nplan 1\nfalse; failure \"Previous command had a non zero exit code.\"\n```\n```\n1..1\nok - Previous command had a non zero exit code.\n```\n\n### Diagnostics\n\nBecause the TAP output is written to stdout; we do not want to polute the\nstdout with the output of other programs. In case you are interested in the\noutput we can use the `diagnostics` function. This will escape the output\naccording to TAP specifications.\n\n```bash ./test diagnostics.t\nplan 1\necho 'some random output from a command' | diagnostics\nsuccess \"Previous command had a zero exit code.\"\n```\n```\n1..1\n# some random output from a command\nok - Previous command had a zero exit code.\n```\n\n### Skip\n\nSkip is great to make sure that the planned test count is still what we expect\nyet it allows us to communicate that certain tests were not run.\n\n```bash ./test skip.t\nplan 2\nskip \"No need to test this.\"\nok \"Is run and is ok.\"\n```\n```\n1..2\nok - # skip No need to test this.\nok - Is run and is ok.\n```\n\n### Skip All\n\nCertain cases we accept that a test does not continue but also doesn't cause\na test failure. We use `skip_all` for those cases. Make sure to not have defined any\nother output. A `skip_all` is most likely to occur at the top of the file before\ntests are run.\n\n\n```bash ./test skip-all.t\nskip_all \"Because that was the intention.\"\n```\n```\n1..0 # skip Because that was the intention.\n```\n\n### Bail\n\nSometimes you want the complete test suite to fail when something happens.\nFor that we use `bail`.\n\nTo test this case we first write a bash-tap test that bails and then check if\nthat actually happens.\n\n```bash tee ./t/bail.bash \u003e /dev/null\n#!/usr/bin/env bash\n\nsource bash-tap\n\nplan 2\nbail \"Reason why it bailed.\" # Optionally you can exit here.\nnot_ok \"Reaches this but ignores it.\"\n```\n\n\u003e Bash-tap leaves it up to the user to exit on bail or not. This is to leave\n\u003e more freedom to the developer as to how and when the process should exit.\n\nNow we test if this test fails when running it with prove test harness.\n\n```bash ./test bail.t\nplan 1\nprove ./t/bail.bash 2\u003e\u00261 | diagnostics\nfailure \"Should bail.\"\n```\n```\n1..1\n# Bailout called.  Further testing stopped:  Reason why it bailed.\n# FAILED--Further testing stopped: Reason why it bailed.\nok - Should bail.\n```\n\nThis process will also exit with a non zero exit code.\n\n```bash bash\nbash ./t/bail.bash\necho $?\n```\n```\n1..2\nBail out! Reason why it bailed.\nnot ok - Reaches this but ignores it.\n1\n```\n\n### Failing pipelines\n\nWhen using pipes in bash, we have to make sure that if one of the processes in\nthat pipeline fails, the whole pipeline also returns a non zero exit code. We\nuse the `set -o pipefail` for that. bash-tap will do this for you when sourcing\nit.\n\n```bash ./test pipefail.t\nplan 1\nls | xargs not-a-command 2\u003e\u00261 | diagnostics\nfailure \"Should fail because not-a-command is not an existant command.\"\n```\n```\n1..1\n# xargs: not-a-command: No such file or directory\nok - Should fail because not-a-command is not an existant command.\n```\n\n### Dash\n\nBesides bash you can also use bash-tap in dash. Dash does not have `source`\nfeature and therefore we have to `cat` to perform the tests. We'll run all\npreviously defined tests using dash.\n\n```bash bash || true\nsource bash-tap\n\ntodo \"Make sure only tests that dash can support are run. (hardcode?)\"\n\nfor file in ./t/*.t; do\n  {\n    printf 'source() { return 0; }\\n'\n    cat bash-tap \"$file\"\n  } | sh - \u003e /dev/null\n  success \"Can run $file.\"\ndone\n\nplan\n```\n```\nnot ok - # TODO Make sure only tests that dash can support are run. (hardcode?)\nok - Can run ./t/append-plan.t.\nnot ok - Can run ./t/bail.t.\nok - Can run ./t/diagnostics.t.\nok - Can run ./t/failure.t.\nok - Can run ./t/ok.t.\nnot ok - Can run ./t/pipefail.t.\nok - Can run ./t/plan.t.\nok - Can run ./t/script-success.t.\nok - Can run ./t/skip-all.t.\nok - Can run ./t/skip.t.\nok - Can run ./t/source-using-path-variable.t.\nok - Can run ./t/source-using-relative-path.t.\nok - Can run ./t/success.t.\nok - Can run ./t/todo.t.\n1..12\n```\n\n### Script Success\n\nWe might also only care if a complete script is run with success.\n\nIn that case simply  call the function script_success at the top of the file.\n\nAll stdout will by piped to diagnostics, the plan will be 1 and the rest of the\nTAP output is either ok or not ok depending on the exit code of the running of\nthe script.\n\n\u003e Does require the file to be executable.\n\n```bash ./test script-success.t\nsource bash-tap\nscript_success\n\necho hello world\n```\n```\n1..1\n# hello world\nok - Script ./t/script-success.t ran successfuly.\n```\n\n## Documentation\n\nThe ./README.md is generated using [Markatzea][markatzea].\n\n```bash\nmarkatzea README.mz \u003e README.md\n```\n\n## Tests\n\nTests are located in prove's default ./t directory. This is how to run all of\nthem:\n\n```bash bash\nprove\n```\n```\nt/append-plan.t ................. ok\nt/bail.t ........................ ok\nt/diagnostics.t ................. ok\nt/failure.t ..................... ok\nt/ok.t .......................... ok\nt/pipefail.t .................... ok\nt/plan.t ........................ skipped: (no reason given)\nt/script-success.t .............. ok\nt/skip-all.t .................... skipped: Because that was the intention.\nt/skip.t ........................ ok\nt/source-using-path-variable.t .. ok\nt/source-using-relative-path.t .. ok\nt/success.t ..................... ok\nt/todo.t ........................ ok\nAll tests successful.\nFiles=14, Tests=15,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.10 cusr  0.00 csys =  0.14 CPU)\nResult: PASS\n```\n\nor to run one you can do the following.\n\n```bash bash\nprove ./t/ok.t\n```\n```\n./t/ok.t .. ok\nAll tests successful.\nFiles=1, Tests=1,  0 wallclock secs ( 0.01 usr +  0.00 sys =  0.01 CPU)\nResult: PASS\n```\n\n## License\n\nGNU General Public License 3.0\n\n[1]:https://github.com/bas080/bash-tap.wiki.git\n[2]:https://github.com/bas080/markatzea\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbas080%2Fbash-tap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbas080%2Fbash-tap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbas080%2Fbash-tap/lists"}