{"id":13787490,"url":"https://github.com/darius/tush","last_synced_at":"2026-01-31T05:07:26.070Z","repository":{"id":419597,"uuid":"39388","full_name":"darius/tush","owner":"darius","description":"Literate testing for command-line programs","archived":false,"fork":false,"pushed_at":"2015-11-30T15:18:15.000Z","size":12,"stargazers_count":57,"open_issues_count":2,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-25T06:02:12.369Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","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/darius.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2008-08-02T06:09:44.000Z","updated_at":"2024-11-30T15:37:23.000Z","dependencies_parsed_at":"2022-08-02T16:01:13.331Z","dependency_job_id":null,"html_url":"https://github.com/darius/tush","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/darius%2Ftush","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darius%2Ftush/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darius%2Ftush/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darius%2Ftush/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darius","download_url":"https://codeload.github.com/darius/tush/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252968052,"owners_count":21833249,"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":[],"created_at":"2024-08-03T20:00:36.681Z","updated_at":"2026-01-31T05:07:26.031Z","avatar_url":"https://github.com/darius.png","language":"Shell","funding_links":[],"categories":["Software \u003ca name=\"software\"\u003e\u003c/a\u003e"],"sub_categories":[],"readme":"tush -- a literate testing shell\n\nThis is sort of a doctest for shellscripts. There are two major pluses:\n\n  * The examples in your documentation get checked automatically.\n  * Tests can be easy to write and to read.\n\nThis style of testing has proved itself in language-specific tools\nlike Python's doctest and E's UpDoc (and FIT for Java, sort of). But\nto test command-line programs it seems to be usual to write\nshellscripts that each set up some files, etc., call on the subject\nprogram, check the result, and clean up. This isn't fun, and less fun\nmeans fewer tests get written. After I started a project involving\nlots of command-line programs I wrote tush instead.\n\n\nTo install it:\n\nCopy bin/* from this directory to somewhere in your PATH.\n\n\nTo use it:\n\nTush looks for transcript-like lines in a file and checks them. For\nexample:\n\n$ echo Hello world\n| Hello world\n\nIf you run 'tush-check README' (where README is this file), it notices\nthe above two lines, executes 'echo Hello world', and checks that\n'Hello world' comes out on the standard output. Assuming the test\npasses, running tush-check succeeds silently. A failing test makes\ntush-check fail and output a diff.\n\nYou aren't limited to invoking the program under test; setup,\nclean-up, checking, etc., work the same way:\n\n$ echo  \u003etest.in 'here is some test input'\n$ echo \u003e\u003etest.in 'and here is some more'\n$ sort test.in | wc -l  # Check: sorting should not change the linecount.\n|        2\n\nWe didn't bother to rm test.in afterwards because we have a crude kind\nof test isolation already: Tush makes a new temporary directory named\ntush-scratch, runs all the commands in the input from within it, then\ndeletes it.\n\nWhat about checking commands that should fail? There are two more\nspecial prefixes. For example:\n\n$ cat nonesuch\n@ cat: nonesuch: No such file or directory\n? 1\n\nThe '@ ' line is like '| ', only for standard error instead of standard\noutput. The '? ' line shows a nonzero exit status.\n\n\nTools:\n\ntush-check was introduced above. It calls tush-run, which runs\ntush-run-raw from within a temporary tush-scratch directory. \n\ntush-run-raw copies its input except for the special-prefixed lines\nintroduced above: '$ ' lines are copied, too, but also executed, with\ntheir outputs/status codes inserted into the output with appropriate\nprefixes, so that for a successful test the output is the same as the\ninput. Input lines starting with '| ', '@ ', or '? ' are dropped.\n\nThe above tools, like 'cat', take any number of files as arguments.\n\n'tush-bless foo' updates foo so that 'tush-check foo' will then pass:\nit changes any output/status-code lines to the actual outputs from\ntush-run. Use this when your program is correct but your test is\nwrong.\n\n\nExamples:\n\nSee the *.tush files in this directory. They're a kind of self-check\nof the Tush implementation, though a weak one, since implementing\ntush-run as 'cat' would pass it.  [XXX do something about that?]\n\n\nEmacs mode:\n\ntush.el lets you pass the file you're editing through tush-run with a\nsingle keystroke. This can go nicely with interactive development\ncombining unit tests with the code under test.\n\n\nAlternatives:\n\nWhy not more like UpDoc or doctest?  [TODO: explain]\n\n\nCredits:\n\nDarius Bacon \u003cdarius@wry.me\u003e\n\nThe 'overwrite' script is from Kernighan and Pike, _The UNIX\nProgramming Environment_, and adapted by Clyde Ingram.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarius%2Ftush","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarius%2Ftush","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarius%2Ftush/lists"}