pax_global_header00006660000000000000000000000064144451336140014517gustar00rootroot0000000000000052 comment=8bdaae2f56e524f8824307d5c443e6353fe0dbd9 aureliojargas-clitest-8bdaae2/000077500000000000000000000000001444513361400165645ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/.devcontainer/000077500000000000000000000000001444513361400213235ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/.devcontainer/devcontainer.json000066400000000000000000000007751444513361400247100ustar00rootroot00000000000000// https://aka.ms/devcontainer.json { "name": "clitest dev", // // https://github.com/aureliojargas/devcontainer "image": "ghcr.io/aureliojargas/devcontainer", // // https://aka.ms/vscode-remote/containers/non-root "remoteUser": "vscode", // // https://github.com/devcontainers/features/tree/main/src "features": { "github-cli": "latest", // Makefile commands are run inside the clitest-dev Docker container "docker-in-docker": "latest" } } aureliojargas-clitest-8bdaae2/.dockerignore000066400000000000000000000000051444513361400212330ustar00rootroot00000000000000.git aureliojargas-clitest-8bdaae2/.editorconfig000066400000000000000000000003251444513361400212410ustar00rootroot00000000000000root = true [*] indent_style = space indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false [*.yml] indent_size = 2 aureliojargas-clitest-8bdaae2/.github/000077500000000000000000000000001444513361400201245ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/.github/workflows/000077500000000000000000000000001444513361400221615ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/.github/workflows/check.yml000066400000000000000000000006071444513361400237640ustar00rootroot00000000000000# https://docs.github.com/en/actions/reference name: Check on: push: pull_request: jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: make docker-build - run: make lint test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: make docker-build - run: make versions - run: make test aureliojargas-clitest-8bdaae2/.gitignore000066400000000000000000000000101444513361400205430ustar00rootroot00000000000000.vscode aureliojargas-clitest-8bdaae2/CHANGELOG.md000066400000000000000000000001361444513361400203750ustar00rootroot00000000000000# clitest changelog The changelog is here: https://github.com/aureliojargas/clitest/releases aureliojargas-clitest-8bdaae2/Dockerfile.dev000066400000000000000000000010001444513361400213220ustar00rootroot00000000000000# clitest-dev # Local Docker image used for clitest development. # # It has all the required tools for linting and testing clitest code. # See Makefile for commands to build and run this image. # # If you're searching for the official clitest Docker image (for users): # https://hub.docker.com/r/aureliojargas/clitest FROM alpine:3.18 # Perl is required by clitest's --regex matching mode RUN apk --no-cache add \ bash dash mksh zsh \ perl \ make \ checkbashisms shellcheck shfmt WORKDIR /mnt aureliojargas-clitest-8bdaae2/LICENSE.txt000066400000000000000000000020711444513361400204070ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2013 Aurelio Jargas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. aureliojargas-clitest-8bdaae2/Makefile000066400000000000000000000021621444513361400202250ustar00rootroot00000000000000# Developer workflow: run locally the same commands the CI will run. # See the .github/workflows/check.yml file for the list of commands. # # By default, the linting and testing targets are run inside the # clitest-dev Docker container. To run them directly on the host, # avoiding the container, unset the `docker_run` variable. Examples: # # make test-bash # test using container's bash # make test-bash docker_run= # test using host's bash docker_image = clitest-dev docker_run = docker run --rm -t -v $$PWD:/mnt $(docker_image) test_cmd = ./clitest --first --progress none test.md default: @echo "Read the comments in the Makefile for help" fmt: $(docker_run) shfmt -w -i 4 -ci -kp -sr clitest lint: $(docker_run) shfmt -d -i 4 -ci -kp -sr clitest $(docker_run) checkbashisms --posix clitest $(docker_run) shellcheck clitest test: test-bash test-dash test-mksh test-sh test-zsh test-%: $(docker_run) $* $(test_cmd) versions: @$(docker_run) sh -c 'apk list 2>/dev/null | cut -d " " -f 1 | sort' docker-build: docker build -t $(docker_image) -f Dockerfile.dev . docker-run: $(docker_run) $(cmd) aureliojargas-clitest-8bdaae2/README.md000066400000000000000000000370151444513361400200510ustar00rootroot00000000000000# clitest – Command Line Tester clitest is a [portable][1] POSIX shell script that performs automatic testing in Unix command lines. It's the same concept as in Python's [doctest][2] module: you document both the commands and their expected output, using the familiar interactive prompt format, and a specialized tool tests them. In fact, the doctest [official][3] description can also be used for clitest: * The **doctest** module searches for pieces of text that look like interactive **Python sessions**, and then executes those **sessions** to verify that they work exactly as shown. * The **clitest** command searches for pieces of text that look like interactive **Unix command lines**, and then executes those **command lines** to verify that they work exactly as shown. ## Download & install The full program is just [a single shell script file][4]. Save it, make it executable and move it to a `$PATH` directory: ```bash curl -sOL https://raw.githubusercontent.com/aureliojargas/clitest/master/clitest chmod +x clitest sudo mv clitest /usr/bin ``` Now check if everything is fine: ``` clitest --help ``` ## Docker image You can also run clitest in a Docker container ([more info in Docker Hub](https://hub.docker.com/r/aureliojargas/clitest)). ``` docker run --rm -t aureliojargas/clitest --help ``` ## Quick Intro Save the commands and their expected output in a text file: ♦ [examples/intro.txt][5] ``` $ echo "Hello World" Hello World $ cd /tmp $ pwd /tmp $ cd "$OLDPWD" $ ``` Use clitest to run these commands and check their output: ```console $ clitest examples/intro.txt #1 echo "Hello World" #2 cd /tmp #3 pwd #4 cd "$OLDPWD" OK: 4 of 4 tests passed $ ``` ## CLI Syntax There's no syntax to learn. The test files are identical to the good old command line interface (CLI) you're so familiar: ♦ [examples/cut.txt][6] ``` $ echo "one:two:three:four:five:six" | cut -d : -f 1 one $ echo "one:two:three:four:five:six" | cut -d : -f 4 four $ echo "one:two:three:four:five:six" | cut -d : -f 1,4 one:four $ echo "one:two:three:four:five:six" | cut -d : -f 4,1 one:four $ echo "one:two:three:four:five:six" | cut -d : -f 1-4 one:two:three:four $ echo "one:two:three:four:five:six" | cut -d : -f 4- four:five:six $ ``` That's it. Just paste your shell session inside a text file and you have a ready-to-use test suite. ```console $ clitest examples/cut.txt #1 echo "one:two:three:four:five:six" | cut -d : -f 1 #2 echo "one:two:three:four:five:six" | cut -d : -f 4 #3 echo "one:two:three:four:five:six" | cut -d : -f 1,4 #4 echo "one:two:three:four:five:six" | cut -d : -f 4,1 #5 echo "one:two:three:four:five:six" | cut -d : -f 1-4 #6 echo "one:two:three:four:five:six" | cut -d : -f 4- OK: 6 of 6 tests passed $ ``` There are more examples and instructions in the [examples folder][10]. For a real-life collection of hundreds of test files, see [funcoeszz test files][24]. ## Testable Documentation Clitest can also **extract and run command lines from documentation**, such as Markdown files. This very `README.md` file you are now reading is testable with `clitest README.md`. All the command lines inside it will be run and checked. No more malfunctioning shell commands in your READMEs, you can have testable documentation. Given the following Markdown sample document: ♦ [examples/cut.md][7] ``` The numeric ranges of the Unix command "cut" ============================================ Use single numbers to extract one specific field: $ echo "one:two:three:four:five:six" | cut -d : -f 1 one $ echo "one:two:three:four:five:six" | cut -d : -f 4 four Use commas to inform more than one field: $ echo "one:two:three:four:five:six" | cut -d : -f 1,4 one:four Note that inverting the order will *not* invert the output: $ echo "one:two:three:four:five:six" | cut -d : -f 4,1 one:four Use an hyphen to inform a range of fields, from one to four: $ echo "one:two:three:four:five:six" | cut -d : -f 1-4 one:two:three:four If you omit the second range number, it matches until the last: $ echo "one:two:three:four:five:six" | cut -d : -f 4- four:five:six cut is cool, isn't it? ``` It is a technical article, not a boring code-only test file. You can read its final (formatted) version [here][7]. You can give this article to clitest, who will identify all the shell command lines inside it, run them and check if the results are the same. ```console $ clitest --prefix tab examples/cut.md #1 echo "one:two:three:four:five:six" | cut -d : -f 1 #2 echo "one:two:three:four:five:six" | cut -d : -f 4 #3 echo "one:two:three:four:five:six" | cut -d : -f 1,4 #4 echo "one:two:three:four:five:six" | cut -d : -f 4,1 #5 echo "one:two:three:four:five:six" | cut -d : -f 1-4 #6 echo "one:two:three:four:five:six" | cut -d : -f 4- OK: 6 of 6 tests passed $ ``` Note the use of `--prefix tab` option, to inform clitest that the code blocks are prefixed by a tab in this Markdown file. For files with 4-spaces indented code blocks, use `--prefix 4`. When using non-indented fenced code blocks (\`\`\`), such as this [README.md][8], no prefix option is needed. Examples of testable documentation handled by clitest: * https://github.com/aureliojargas/txt2regex/blob/master/tests/features.md * https://github.com/aureliojargas/txt2regex/blob/master/tests/cmdline.md * https://github.com/aureliojargas/sedsed/blob/master/test/command_line.md * https://github.com/aureliojargas/replace/blob/master/README.md * https://github.com/aureliojargas/clitest/blob/master/test.md * https://github.com/caarlos0/jvm/blob/master/tests/test.clitest.md * https://github.com/caarlos0/git-add-remote/blob/master/tests/suite.clitest.md ## Alternative Syntax: Inline Output Now a nice extension to the original idea. Using the special marker `#=>` you can embed the expected command output at the end of the command line. ```console $ echo "foo" #=> foo $ echo $((10 + 2)) #=> 12 ``` This is the same as doing: ```console $ echo "foo" foo $ echo $((10 + 2)) 12 $ ``` Inline outputs are very readable when testing series of commands that result in short texts. ```console $ echo "abcdef" | cut -c 1 #=> a $ echo "abcdef" | cut -c 4 #=> d $ echo "abcdef" | cut -c 1,4 #=> ad $ echo "abcdef" | cut -c 1-4 #=> abcd ``` > Note: If needed, you can change this marker (i.e., to `#→` or `###`) > at the top of the script or using the `--inline-prefix` option. ## Advanced Tests When using the `#=>` marker, you can take advantage of special options to change the default output matching method. ```console $ head /etc/passwd #=> --lines 10 $ tac /etc/passwd | tac #=> --file /etc/passwd $ cat /etc/passwd #=> --egrep ^root: $ echo $((2 + 10)) #=> --regex ^\d+$ $ make test #=> --exit 0 $ pwd #=> --eval echo $PWD ``` * Using `#=> --lines` the test will pass if the command output has exactly `N` lines. Handy when the output text is variable (unpredictable), but the number of resulting lines is constant. * Using `#=> --file` the test will pass if the command output matches the contents of an external file. Useful to organize long/complex outputs into files. * Using `#=> --egrep` the test will pass if `grep -E` matches at least one line of the command output. * Using `#=> --regex` the test will pass if the command output is matched by a [Perl regular expression][9]. A multiline output is matched as a single string, with inner `\n`'s. Use the `(?ims)` modifiers when needed. * Using `#=> --exit` the test will pass if the exit code of the command is equal to the code specified. Useful when testing commands that generate variable output (or no output at all), and the exit code is the best indication of success. Both STDIN and STDOUT are ignored when using this option. * Using `#=> --eval` the test will pass if both commands result in the same output. Useful to expand variables which store the full or partial output. ## Options ```console $ clitest --help Usage: clitest [options] Options: -1, --first Stop execution upon first failed test -l, --list List all the tests (no execution) -L, --list-run List all the tests with OK/FAIL status -t, --test RANGE Run specific tests, by number (1,2,4-7) -s, --skip RANGE Skip specific tests, by number (1,2,4-7) --pre-flight COMMAND Execute command before running the first test --post-flight COMMAND Execute command after running the last test -q, --quiet Quiet operation, no output shown -V, --version Show program version and exit Customization options: -P, --progress TYPE Set progress indicator: test, number, dot, none --color WHEN Set when to use colors: auto, always, never --diff-options OPTIONS Set diff command options (default: '-u') --inline-prefix PREFIX Set inline output prefix (default: '#=> ') --prefix PREFIX Set command line prefix (default: '') --prompt STRING Set prompt string (default: '$ ') $ ``` ## Exit codes * `0` - All tests passed, or normal operation (--help, --list, …) * `1` - One or more tests have failed * `2` - An error occurred (file not found, invalid range, …) ## Fail fast Use the `--first` option (or the short version `-1`) to abort the execution when any test fails. Useful for Continuous Integration (CI), or when running sequential tests where the next test depends on the correct result of the previous. ## Quiet operation When automating the tests execution, use `--quiet` to show no output and just check the exit code to make sure all tests have passed. Using `--first` to fail fast is also a good idea in this case. ```bash if clitest --quiet --first tests.txt then # all tests passed else # one or more tests failed :( fi ``` ## Run specific tests To rerun a specific problematic test, or to limit the execution to a set of tests, use `--test`. To ignore one or more tests, use `--skip`. If needed, you can combine both options to inform a very specific test range. Examples: ```bash clitest --test 1-10 tests.txt # Run the first 10 tests clitest --test 1,2,6-8 tests.txt # Run tests #1, #2, #6, #7 and #8 clitest --skip 11,15 tests.txt # Run all tests, except #11 and #15 clitest -t 1-10 -s 5 tests.txt # Run first 10 tests, but skip #5 ``` ## Pre/post scripts You can run a preparing script or command before the first test with `--pre-flight`, for setting env variables and create auxiliary files. At the end of all tests, run a final cleanup script/command with `--post-flight` to remove temporary files or other transient data. ```bash clitest --pre-flight ./test-init.sh --post-flight 'rm *.tmp' tests.txt ``` ## Customization Use the customization options to extract and test command lines from documents or wiki pages. For example, to test all the command line examples listed inside a Markdown file using the 4-spaces syntax for code blocks: ```bash clitest --prefix 4 README.md ``` Or maybe you use a different prompt (`$PS1`) in your documentation? ```bash clitest --prefix 4 --prompt '[john@localhost ~]$ ' README.md ``` ## Nerdiness * Use any text file format for the tests, it doesn't matter. The command lines just need to be grepable and have a fixed prefix (or even none). Even Windows text files (CR+LF) will work fine. * The command line power is available in your test files: use variables, pipes, redirection, create files, folders, move around… * All the commands are tested using a single shell session. This means that variables, aliases and functions defined in one test will persist in the following tests. * Both STDOUT and STDERR are captured, so you can also test error messages. * To test STDOUT/STDERR and the exit code at the same time, add a `;echo $?` after the command. * Use an empty `$` prompt to close the last command output. * In the output, every single char (blank or not) counts. Any difference will cause a test to fail. To ignore the difference in blanks, use `--diff-options '-u -w'`. * Unlike doctest's ``, in clitest blank lines in the command output aren't a problem. Just insert them normally. * To test outputs with no final `\n`, such as `printf foo`, use `#=> --regex ^foo$`. * In multifile mode, the current folder (`$PWD`) is reset when starting to test a new file. This avoids that a `cd` command in a previous file will affect the next. * Multiline prompts (`$PS2`) are not yet supported. * Ellipsis (as in doctest) are not supported. Use `#=> --regex` instead. * Simple examples in [examples/][10]. Hardcore examples in [test.md][11] and [test/][12], the clitest own test-suite. ## Choose the execution shell The clitest shebang is `#!/bin/sh`. That's the default shell that will be used to run your test command lines. Depending on the system, that path points to a different shell, such as ash, dash, or bash ([running in POSIX mode][23]). To force your test commands to always run on a specific shell, just call the desired shell before: ```bash clitest tests.txt # Uses /bin/sh bash clitest tests.txt # Uses Bash ksh clitest tests.txt # Uses Korn Shell ``` ## Portability This script was carefully coded to be portable between [POSIX][13] shells. It's code is validated by [checkbashisms][25] and [shellcheck][26]. To make sure it keeps working as expected, after every change clitest is automatically tested in the CI, using the following shells: - bash - dash - ksh - sh (busybox) - zsh > Fish shell is not supported (it's not POSIX), but you > can use [doctest.fish][27] instead. Portability issues are considered serious bugs, please [report them][14]! Developers: Learn more about portability in POSIX shells: * [How to make bash scripts work in dash][15] * [Ubuntu — Dash as /bin/sh][16] * [Rich’s sh (POSIX shell) tricks][17] * [lintsh][18] * [Official POSIX specification: Shell & Utilities][19] ## [KISS][20] A shell script to test shell commands. No other language or environment involved. ## Meta * Author: [Aurelio Jargas][21] * Created: 2013-07-24 * Language: Shell Script * License: [MIT][22] [1]: #portability [2]: http://en.wikipedia.org/wiki/Doctest [3]: http://docs.python.org/3/library/doctest.html [4]: https://raw.github.com/aureliojargas/clitest/master/clitest [5]: https://github.com/aureliojargas/clitest/blob/master/examples/intro.txt [6]: https://github.com/aureliojargas/clitest/blob/master/examples/cut.txt [7]: https://github.com/aureliojargas/clitest/blob/master/examples/cut.md [8]: https://github.com/aureliojargas/clitest/blob/master/README.md [9]: http://perldoc.perl.org/perlre.html [10]: https://github.com/aureliojargas/clitest/tree/master/examples [11]: https://github.com/aureliojargas/clitest/blob/master/test.md [12]: https://github.com/aureliojargas/clitest/blob/master/test/ [13]: http://en.wikipedia.org/wiki/POSIX [14]: https://github.com/aureliojargas/clitest/issues [15]: http://mywiki.wooledge.org/Bashism [16]: https://wiki.ubuntu.com/DashAsBinSh [17]: http://www.etalabs.net/sh_tricks.html [18]: http://code.dogmap.org/lintsh/ [19]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html [20]: http://en.wikipedia.org/wiki/KISS_principle [21]: http://aurelio.net/about.html [22]: https://github.com/aureliojargas/clitest/blob/master/LICENSE.txt [23]: https://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html [24]: https://github.com/funcoeszz/funcoeszz/tree/master/testador [25]: https://linux.die.net/man/1/checkbashisms [26]: https://www.shellcheck.net/ [27]: https://github.com/aureliojargas/doctest.fish aureliojargas-clitest-8bdaae2/clitest000077500000000000000000000770721444513361400201760ustar00rootroot00000000000000#!/bin/sh # clitest - Tester for Unix command lines # # Author: Aurelio Jargas (http://aurelio.net) # Created: 2013-07-24 # License: MIT # GitHub: https://github.com/aureliojargas/clitest # # POSIX shell script: # This script is carefully coded to be compatible with POSIX shells. # It is currently tested in bash, dash, ksh, zsh and busybox's sh. # # Exit codes: # 0 All tests passed, or normal operation (--help, --list, ...) # 1 One or more tests have failed # 2 An error occurred (file not found, invalid range, ...) # # Test environment: # By default, the tests will run in the current working directory ($PWD). # You can change to another dir normally using 'cd' inside the test file. # All the tests are executed in the same shell session, using eval. Test # data such as variables and working directory will persist between tests. # # Namespace: # All variables and functions in this script are prefixed by 'tt_' to # avoid clashing with test's variables, functions, aliases and commands. tt_my_name="$(basename "$0")" tt_my_url='https://github.com/aureliojargas/clitest' tt_my_version='0.5.0' # Customization (if needed, edit here or use the command line options) tt_prefix='' tt_prompt='$ ' tt_inline_prefix='#=> ' tt_diff_options='-u' tt_color_mode='auto' # auto, always, never tt_progress='test' # test, number, dot, none # End of customization # --help message, keep it simple, short and informative tt_my_help="\ Usage: $tt_my_name [options] Options: -1, --first Stop execution upon first failed test -l, --list List all the tests (no execution) -L, --list-run List all the tests with OK/FAIL status -t, --test RANGE Run specific tests, by number (1,2,4-7) -s, --skip RANGE Skip specific tests, by number (1,2,4-7) --pre-flight COMMAND Execute command before running the first test --post-flight COMMAND Execute command after running the last test -q, --quiet Quiet operation, no output shown -V, --version Show program version and exit Customization options: -P, --progress TYPE Set progress indicator: test, number, dot, none --color WHEN Set when to use colors: auto, always, never --diff-options OPTIONS Set diff command options (default: '$tt_diff_options') --inline-prefix PREFIX Set inline output prefix (default: '$tt_inline_prefix') --prefix PREFIX Set command line prefix (default: '$tt_prefix') --prompt STRING Set prompt string (default: '$tt_prompt') See also: $tt_my_url" # Flags (0=off, 1=on), most can be altered by command line options tt_debug=0 tt_use_colors=0 tt_stop_on_first_fail=0 tt_separator_line_shown=0 # The output mode values are mutually exclusive tt_output_mode='normal' # normal, quiet, list, list-run # Globals (all variables are globals, for better portability) tt_nr_files=0 tt_nr_total_tests=0 tt_nr_total_fails=0 tt_nr_total_skips=0 tt_nr_file_tests=0 tt_nr_file_fails=0 tt_nr_file_skips=0 tt_nr_file_ok=0 tt_files_stats= tt_original_dir=$(pwd) tt_pre_command= tt_post_command= tt_run_range= tt_run_range_data= tt_skip_range= tt_skip_range_data= tt_failed_range= tt_temp_dir= tt_test_file= tt_input_line= tt_line_number=0 tt_test_number=0 tt_test_line_number=0 tt_test_command= tt_test_inline= tt_test_mode= tt_test_status=2 tt_test_output= tt_test_exit_code= tt_test_diff= tt_test_ok_text= tt_missing_nl=0 # Special handy chars tt_tab=' ' tt_nl=' ' ### Utilities # shellcheck disable=SC2317 # Function is reachable (invoked by a trap) tt_clean_up() { test -n "$tt_temp_dir" && rm -rf "$tt_temp_dir" } tt_message() { test "$tt_output_mode" = 'quiet' && return 0 test $tt_missing_nl -eq 1 && echo printf '%s\n' "$*" tt_separator_line_shown=0 tt_missing_nl=0 } tt_message_part() { # no line break test "$tt_output_mode" = 'quiet' && return 0 printf '%s' "$*" tt_separator_line_shown=0 tt_missing_nl=1 } tt_error() { test $tt_missing_nl -eq 1 && echo printf '%s\n' "$tt_my_name: Error: $1" >&2 exit 2 } tt_debug() { # $1=id, $2=contents test $tt_debug -ne 1 && return 0 if test INPUT_LINE = "$1"; then # Original input line is all cyan and preceded by separator line printf -- "${tt_color_cyan}%s${tt_color_off}\n" "$(tt_separator_line)" printf -- "${tt_color_cyan}-- %10s[%s]${tt_color_off}\n" "$1" "$2" else # Highlight tabs and the (last) inline prefix printf -- "${tt_color_cyan}-- %10s[${tt_color_off}%s${tt_color_cyan}]${tt_color_off}\n" "$1" "$2" | sed "/LINE_CMD/ s/\(.*\)\($tt_inline_prefix\)/\1${tt_color_red}\2${tt_color_off}/" | sed "s/$tt_tab/${tt_color_green}${tt_color_off}/g" fi } tt_separator_line() { printf "%${COLUMNS}s" ' ' | tr ' ' - } tt_list_test() { # $1=normal|list|ok|fail # Show the test command in normal mode, --list and --list-run case "$1" in normal | list) # Normal line, no color, no stamp (--list) tt_message "#${tt_test_number}${tt_tab}${tt_test_command}" ;; ok) # Green line or OK stamp (--list-run) if test $tt_use_colors -eq 1; then tt_message "${tt_color_green}#${tt_test_number}${tt_tab}${tt_test_command}${tt_color_off}" else tt_message "#${tt_test_number}${tt_tab}OK${tt_tab}${tt_test_command}" fi ;; fail) # Red line or FAIL stamp (--list-run) if test $tt_use_colors -eq 1; then tt_message "${tt_color_red}#${tt_test_number}${tt_tab}${tt_test_command}${tt_color_off}" else tt_message "#${tt_test_number}${tt_tab}FAIL${tt_tab}${tt_test_command}" fi ;; esac } tt_parse_range() { # $1=range # Parse numeric ranges and output them in an expanded format # # Supported formats Expanded # ------------------------------------------------------ # Single: 1 :1: # List: 1,3,4,7 :1:3:4:7: # Range: 1-4 :1:2:3:4: # Mixed: 1,3,4-7,11,13-15 :1:3:4:5:6:7:11:13:14:15: # # Reverse ranges and repeated/unordered numbers are ok. # Later we will just grep for :number: in each test. case "$1" in 0 | '') # No range, nothing to do return 0 ;; *[!0-9,-]*) # Error: strange chars, not 0123456789,- return 1 ;; esac # OK, all valid chars in range, let's parse them tt_part= tt_n1= tt_n2= tt_swap= tt_range_data=':' # :1:2:4:7: # Loop each component: a number or a range for tt_part in $(echo "$1" | tr , ' '); do # If there's an hyphen, it's a range case "$tt_part" in *-*) # Error: Invalid range format, must be: number-number echo "$tt_part" | grep '^[0-9][0-9]*-[0-9][0-9]*$' > /dev/null || return 1 tt_n1=${tt_part%-*} tt_n2=${tt_part#*-} # Negative range, let's just reverse it (5-1 => 1-5) if test "$tt_n1" -gt "$tt_n2"; then tt_swap=$tt_n1 tt_n1=$tt_n2 tt_n2=$tt_swap fi # Expand the range (1-4 => 1:2:3:4) tt_part=$tt_n1: while test "$tt_n1" -ne "$tt_n2"; do tt_n1=$((tt_n1 + 1)) tt_part=$tt_part$tt_n1: done tt_part=${tt_part%:} ;; esac # Append the number or expanded range to the holder test "$tt_part" != 0 && tt_range_data=$tt_range_data$tt_part: done test "$tt_range_data" != ':' && echo "$tt_range_data" return 0 } tt_reset_test_data() { tt_test_command= tt_test_inline= tt_test_mode= tt_test_status=2 tt_test_output= tt_test_diff= tt_test_ok_text= } tt_run_test() { tt_test_number=$((tt_test_number + 1)) tt_nr_total_tests=$((tt_nr_total_tests + 1)) tt_nr_file_tests=$((tt_nr_file_tests + 1)) # Run range on: skip this test if it's not listed in $tt_run_range_data if test -n "$tt_run_range_data" && test "$tt_run_range_data" = "${tt_run_range_data#*:"$tt_test_number":}"; then tt_nr_total_skips=$((tt_nr_total_skips + 1)) tt_nr_file_skips=$((tt_nr_file_skips + 1)) tt_reset_test_data return 0 fi # Skip range on: skip this test if it's listed in $tt_skip_range_data # Note: --skip always wins over --test, regardless of order if test -n "$tt_skip_range_data" && test "$tt_skip_range_data" != "${tt_skip_range_data#*:"$tt_test_number":}"; then tt_nr_total_skips=$((tt_nr_total_skips + 1)) tt_nr_file_skips=$((tt_nr_file_skips + 1)) tt_reset_test_data return 0 fi case "$tt_output_mode" in normal) # Normal mode: show progress indicator case "$tt_progress" in test) tt_list_test normal ;; number) tt_message_part "$tt_test_number " ;; none) : ;; *) tt_message_part "$tt_progress" ;; esac ;; list) # List mode: just show the command and return (no execution) tt_list_test list tt_reset_test_data return 0 ;; esac tt_debug EVAL "$tt_test_command" # Execute the test command, saving output (STDOUT and STDERR) eval "$tt_test_command" > "$tt_test_output_file" 2>&1 < /dev/null tt_test_exit_code=$? tt_debug OUTPUT "$(cat "$tt_test_output_file")" # The command output matches the expected output? case $tt_test_mode in output) printf %s "$tt_test_ok_text" > "$tt_test_ok_file" # shellcheck disable=SC2086 # diff options should be split tt_test_diff=$(diff $tt_diff_options "$tt_test_ok_file" "$tt_test_output_file") tt_test_status=$? ;; text) # Inline OK text represents a full line, with \n printf '%s\n' "$tt_test_inline" > "$tt_test_ok_file" # shellcheck disable=SC2086 # diff options should be split tt_test_diff=$(diff $tt_diff_options "$tt_test_ok_file" "$tt_test_output_file") tt_test_status=$? ;; eval) eval "$tt_test_inline" > "$tt_test_ok_file" # shellcheck disable=SC2086 # diff options should be split tt_test_diff=$(diff $tt_diff_options "$tt_test_ok_file" "$tt_test_output_file") tt_test_status=$? ;; lines) tt_test_output=$(sed -n '$=' "$tt_test_output_file") test -z "$tt_test_output" && tt_test_output=0 test "$tt_test_output" -eq "$tt_test_inline" tt_test_status=$? tt_test_diff="Expected $tt_test_inline lines, got $tt_test_output." ;; file) # If path is relative, make it relative to the test file path, not $PWD if test "$tt_test_inline" = "${tt_test_inline#/}"; then tt_test_inline="$(dirname "$tt_test_file")/$tt_test_inline" fi # Abort when ok file not found/readable if test ! -f "$tt_test_inline" || test ! -r "$tt_test_inline"; then tt_error "cannot read inline output file '$tt_test_inline', from line $tt_line_number of $tt_test_file" fi # shellcheck disable=SC2086 # diff options should be split tt_test_diff=$(diff $tt_diff_options "$tt_test_inline" "$tt_test_output_file") tt_test_status=$? ;; egrep) grep -E "$tt_test_inline" "$tt_test_output_file" > /dev/null tt_test_status=$? # Test failed: the regex not matched if test $tt_test_status -eq 1; then tt_test_diff="egrep '$tt_test_inline' failed in:$tt_nl$(cat "$tt_test_output_file")" # Regex errors are common and user must take action to fix them elif test $tt_test_status -gt 1; then tt_error "check your inline egrep regex at line $tt_line_number of $tt_test_file" fi ;; perl | regex) # Escape regex delimiter (if any) inside the regex: ' => \' if test "$tt_test_inline" != "${tt_test_inline#*\'}"; then tt_test_inline=$(printf %s "$tt_test_inline" | sed "s/'/\\\\'/g") fi # Note: -0777 to get the full file contents as a single string perl -0777 -ne "exit(!m'$tt_test_inline')" "$tt_test_output_file" tt_test_status=$? case $tt_test_status in 0) # Test matched, nothing to do : ;; 1) # Test failed: the regex not matched tt_test_diff="Perl regex '$tt_test_inline' not matched in:$tt_nl$(cat "$tt_test_output_file")" ;; 127) # Perl not found :( tt_error "Perl not found. It's needed by --$tt_test_mode at line $tt_line_number of $tt_test_file" ;; 255) # Regex syntax errors are common and user must take action to fix them tt_error "check your inline Perl regex at line $tt_line_number of $tt_test_file" ;; *) tt_error "unknown error when running Perl for --$tt_test_mode at line $tt_line_number of $tt_test_file" ;; esac ;; exit) test "$tt_test_exit_code" -eq "$tt_test_inline" tt_test_status=$? tt_test_diff="Expected exit code $tt_test_inline, got $tt_test_exit_code" ;; *) tt_error "unknown test mode '$tt_test_mode'" ;; esac # Test failed :( if test $tt_test_status -ne 0; then tt_nr_file_fails=$((tt_nr_file_fails + 1)) tt_nr_total_fails=$((tt_nr_total_fails + 1)) tt_failed_range="$tt_failed_range$tt_test_number," # Decide the message format if test "$tt_output_mode" = 'list-run'; then # List mode tt_list_test fail else # Normal mode: show FAILED message and the diff if test $tt_separator_line_shown -eq 0; then # avoid dups tt_message "${tt_color_red}$(tt_separator_line)${tt_color_off}" fi tt_message "${tt_color_red}[FAILED #$tt_test_number, line $tt_test_line_number] $tt_test_command${tt_color_off}" tt_message "$tt_test_diff" | sed '1 { /^--- / { N; /\n+++ /d; }; }' # no ---/+++ headers tt_message "${tt_color_red}$(tt_separator_line)${tt_color_off}" tt_separator_line_shown=1 fi # Should I abort now? if test $tt_stop_on_first_fail -eq 1; then exit 1 fi # Test OK else test "$tt_output_mode" = 'list-run' && tt_list_test ok fi tt_reset_test_data } tt_process_test_file() { # Reset counters tt_nr_file_tests=0 tt_nr_file_fails=0 tt_nr_file_skips=0 tt_line_number=0 tt_test_line_number=0 # Loop for each line of input file # Note: changing IFS to avoid right-trimming of spaces/tabs # Note: read -r to preserve the backslashes while IFS='' read -r tt_input_line || test -n "$tt_input_line"; do tt_line_number=$((tt_line_number + 1)) tt_debug INPUT_LINE "$tt_input_line" case "$tt_input_line" in "$tt_prefix$tt_prompt" | "$tt_prefix${tt_prompt% }" | "$tt_prefix$tt_prompt ") # Prompt alone: closes previous command line (if any) tt_debug 'LINE_$' "$tt_input_line" # Run pending tests test -n "$tt_test_command" && tt_run_test ;; "$tt_prefix$tt_prompt"*) # This line is a command line to be tested tt_debug LINE_CMD "$tt_input_line" # Run pending tests test -n "$tt_test_command" && tt_run_test # Remove the prompt tt_test_command="${tt_input_line#"$tt_prefix$tt_prompt"}" # Save the test's line number for future messages tt_test_line_number=$tt_line_number # This is a special test with inline output? if printf '%s\n' "$tt_test_command" | grep "$tt_inline_prefix" > /dev/null; then # Separate command from inline output tt_test_command="${tt_test_command%"$tt_inline_prefix"*}" tt_test_inline="${tt_input_line##*"$tt_inline_prefix"}" tt_debug NEW_CMD "$tt_test_command" tt_debug OK_INLINE "$tt_test_inline" # Maybe the OK text has options? case "$tt_test_inline" in '--egrep '*) tt_test_inline=${tt_test_inline#--egrep } tt_test_mode='egrep' ;; '--regex '*) # alias to --perl tt_test_inline=${tt_test_inline#--regex } tt_test_mode='regex' ;; '--perl '*) tt_test_inline=${tt_test_inline#--perl } tt_test_mode='perl' ;; '--file '*) tt_test_inline=${tt_test_inline#--file } tt_test_mode='file' ;; '--lines '*) tt_test_inline=${tt_test_inline#--lines } tt_test_mode='lines' ;; '--exit '*) tt_test_inline=${tt_test_inline#--exit } tt_test_mode='exit' ;; '--eval '*) tt_test_inline=${tt_test_inline#--eval } tt_test_mode='eval' ;; '--text '*) tt_test_inline=${tt_test_inline#--text } tt_test_mode='text' ;; *) tt_test_mode='text' ;; esac tt_debug OK_TEXT "$tt_test_inline" # There must be a number in --lines and --exit if test "$tt_test_mode" = 'lines' || test "$tt_test_mode" = 'exit'; then case "$tt_test_inline" in '' | *[!0-9]*) tt_error "--$tt_test_mode requires a number. See line $tt_line_number of $tt_test_file" ;; esac fi # An empty inline parameter is an error user must see if test -z "$tt_test_inline" && test "$tt_test_mode" != 'text'; then tt_error "empty --$tt_test_mode at line $tt_line_number of $tt_test_file" fi # Since we already have the command and the output, run test tt_run_test else # It's a normal command line, output begins in next line tt_test_mode='output' tt_debug NEW_CMD "$tt_test_command" fi ;; *) # Test output, blank line or comment tt_debug 'LINE_MISC' "$tt_input_line" # Ignore this line if there's no pending test test -n "$tt_test_command" || continue # Required prefix is missing: we just left a command block if test -n "$tt_prefix" && test "${tt_input_line#"$tt_prefix"}" = "$tt_input_line"; then tt_debug BLOCK_OUT "$tt_input_line" # Run the pending test and we're done in this line tt_run_test continue fi # This line is a test output, save it (without prefix) tt_test_ok_text="$tt_test_ok_text${tt_input_line#"$tt_prefix"}$tt_nl" tt_debug OK_TEXT "${tt_input_line#"$tt_prefix"}" ;; esac done < "$tt_temp_file" tt_debug LOOP_OUT "\$tt_test_command=$tt_test_command" # Run pending tests test -n "$tt_test_command" && tt_run_test } tt_make_temp_dir() { # Create private temporary dir and sets global $tt_temp_dir. # http://mywiki.wooledge.org/BashFAQ/062 # Prefer mktemp when available tt_temp_dir=$(mktemp -d "${TMPDIR:-/tmp}/clitest.XXXXXX" 2> /dev/null) && return 0 # No mktemp, let's create the dir manually # shellcheck disable=SC2015 tt_temp_dir="${TMPDIR:-/tmp}/clitest.$(awk 'BEGIN { srand(); print rand() }').$$" && mkdir -m 700 "$tt_temp_dir" || tt_error "cannot create temporary dir: $tt_temp_dir" } ### Init process # Handle command line options while test "${1#-}" != "$1"; do case "$1" in -1 | --first) shift tt_stop_on_first_fail=1 ;; -l | --list) shift tt_output_mode='list' ;; -L | --list-run) shift tt_output_mode='list-run' ;; -q | --quiet) shift tt_output_mode='quiet' ;; -t | --test) shift tt_run_range="$1" shift ;; -s | --skip) shift tt_skip_range="$1" shift ;; --pre-flight) shift tt_pre_command="$1" shift ;; --post-flight) shift tt_post_command="$1" shift ;; -P | --progress) shift tt_progress="$1" tt_output_mode='normal' shift ;; --color | --colour) shift tt_color_mode="$1" shift ;; --diff-options) shift tt_diff_options="$1" shift ;; --inline-prefix) shift tt_inline_prefix="$1" shift ;; --prefix) shift tt_prefix="$1" shift ;; --prompt) shift tt_prompt="$1" shift ;; -h | --help) printf '%s\n' "$tt_my_help" exit 0 ;; -V | --version) printf '%s %s\n' "$tt_my_name" "$tt_my_version" exit 0 ;; --debug) # Undocumented dev-only option shift tt_debug=1 ;; --) # No more options to process shift break ;; -) # Argument - means "read test file from STDIN" break ;; *) tt_error "invalid option $1" ;; esac done # Command line options consumed, now it's just the files tt_nr_files=$# # No files? if test $tt_nr_files -eq 0; then tt_error 'no test file informed (try --help)' fi # Handy shortcuts for prefixes case "$tt_prefix" in tab) tt_prefix="$tt_tab" ;; 0) tt_prefix='' ;; [1-9] | [1-9][0-9]) # 1-99 # convert number to spaces: 2 => ' ' tt_prefix=$(printf "%${tt_prefix}s" ' ') ;; *\\*) tt_prefix="$(printf %b "$tt_prefix")" # expand \t and others ;; esac # Validate and normalize progress value if test "$tt_output_mode" = 'normal'; then case "$tt_progress" in test) : ;; number | n | [0-9]) tt_progress='number' ;; dot | .) tt_progress='.' ;; none | no) tt_progress='none' ;; ?) # Single char, use it as the progress : ;; *) tt_error "invalid value '$tt_progress' for --progress. Use: test, number, dot or none." ;; esac fi # Will we use colors in the output? case "$tt_color_mode" in always | yes | y) tt_use_colors=1 ;; never | no | n) tt_use_colors=0 ;; auto | a) # The auto mode will use colors if the output is a terminal # Note: test -t is in POSIX if test -t 1; then tt_use_colors=1 else tt_use_colors=0 fi ;; *) tt_error "invalid value '$tt_color_mode' for --color. Use: auto, always or never." ;; esac # Set colors # Remember: colors must be readable in dark and light backgrounds # Customization: tweak the numbers after [ to adjust the colors if test $tt_use_colors -eq 1; then tt_color_red=$( printf '\033[31m') # fail tt_color_green=$(printf '\033[32m') # ok tt_color_cyan=$( printf '\033[36m') # debug tt_color_off=$( printf '\033[m') fi # Find the terminal width # The COLUMNS env var is set by Bash (must be exported in ~/.bashrc). # In other shells, try to use 'tput cols' (not POSIX). # If not, defaults to 50 columns, a conservative amount. : ${COLUMNS:=$(tput cols 2> /dev/null)} : "${COLUMNS:=50}" # Parse and validate --test option value, if informed tt_run_range_data=$(tt_parse_range "$tt_run_range") if test $? -ne 0; then tt_error "invalid argument for -t or --test: $tt_run_range" fi # Parse and validate --skip option value, if informed tt_skip_range_data=$(tt_parse_range "$tt_skip_range") if test $? -ne 0; then tt_error "invalid argument for -s or --skip: $tt_skip_range" fi ### Real execution begins here trap tt_clean_up EXIT # Temporary files (using files because <(...) is not portable) tt_make_temp_dir # sets global $tt_temp_dir tt_temp_file="$tt_temp_dir/temp.txt" tt_stdin_file="$tt_temp_dir/stdin.txt" tt_test_ok_file="$tt_temp_dir/ok.txt" tt_test_output_file="$tt_temp_dir/output.txt" # Some preparing command to run before all the tests? if test -n "$tt_pre_command"; then eval "$tt_pre_command" || tt_error "pre-flight command failed with status=$?: $tt_pre_command" fi # For each input file in $@ for tt_test_file; do # Some tests may 'cd' to another dir, we need to get back # to preserve the relative paths of the input files cd "$tt_original_dir" || tt_error "cannot enter starting directory $tt_original_dir" # Support using '-' to read the test file from STDIN if test "$tt_test_file" = '-'; then tt_test_file="$tt_stdin_file" cat > "$tt_test_file" fi # Abort when test file is a directory if test -d "$tt_test_file"; then tt_error "input file is a directory: $tt_test_file" fi # Abort when test file not found/readable if test ! -r "$tt_test_file"; then tt_error "cannot read input file: $tt_test_file" fi # In multifile mode, identify the current file if test $tt_nr_files -gt 1; then case "$tt_output_mode" in normal) # Normal mode, show message with filename case "$tt_progress" in test | none) tt_message "Testing file $tt_test_file" ;; *) test $tt_missing_nl -eq 1 && echo tt_message_part "Testing file $tt_test_file " ;; esac ;; list | list-run) # List mode, show ------ and the filename tt_message "$(tt_separator_line | cut -c 1-40)" "$tt_test_file" ;; esac fi # Convert Windows files (CRLF) to the Unix format (LF) # Note: the temporary file is required, because doing "sed | while" opens # a subshell and global vars won't be updated outside the loop. sed "s/$(printf '\r')$//" "$tt_test_file" > "$tt_temp_file" # The magic happens here tt_process_test_file # Abort when no test found (and no active range with --test or --skip) if test $tt_nr_file_tests -eq 0 && test -z "$tt_run_range_data" && test -z "$tt_skip_range_data"; then tt_error "no test found in input file: $tt_test_file" fi # Save file stats tt_nr_file_ok=$((tt_nr_file_tests - tt_nr_file_fails - tt_nr_file_skips)) tt_files_stats="$tt_files_stats$tt_nr_file_ok $tt_nr_file_fails $tt_nr_file_skips$tt_nl" # Dots mode: any missing new line? # Note: had to force tt_missing_nl=0, even when it's done in tt_message :/ test $tt_missing_nl -eq 1 && tt_missing_nl=0 && tt_message done # Some clean up command to run after all the tests? if test -n "$tt_post_command"; then eval "$tt_post_command" || tt_error "post-flight command failed with status=$?: $tt_post_command" fi #----------------------------------------------------------------------- # From this point on, it's safe to use non-prefixed global vars #----------------------------------------------------------------------- # Range active, but no test matched :( if test $tt_nr_total_tests -eq $tt_nr_total_skips; then if test -n "$tt_run_range_data" && test -n "$tt_skip_range_data"; then tt_error "no test found. The combination of -t and -s resulted in no tests." elif test -n "$tt_run_range_data"; then tt_error "no test found for the specified number or range '$tt_run_range'" elif test -n "$tt_skip_range_data"; then tt_error "no test found. Maybe '--skip $tt_skip_range' was too much?" fi fi # List mode has no stats if test "$tt_output_mode" = 'list' || test "$tt_output_mode" = 'list-run'; then if test $tt_nr_total_fails -eq 0; then exit 0 else exit 1 fi fi # Show stats # Data: # $tt_files_stats -> "100 0 23 \n 12 34 0" # $@ -> foo.sh bar.sh # Output: # ok fail skip # 100 0 23 foo.sh # 12 34 0 bar.sh if test $tt_nr_files -gt 1 && test "$tt_output_mode" != 'quiet'; then echo printf ' %5s %5s %5s\n' ok fail skip printf %s "$tt_files_stats" | while IFS=' ' read -r ok fail skip; do printf ' %5s %5s %5s %s\n' "$ok" "$fail" "$skip" "$1" shift done | sed 's/ 0/ -/g' # hide zeros echo fi # The final message: OK or FAIL? # OK: 123 of 123 tests passed # OK: 100 of 123 tests passed (23 skipped) # FAIL: 123 of 123 tests failed # FAIL: 100 of 123 tests failed (23 skipped) skips= if test $tt_nr_total_skips -gt 0; then skips=" ($tt_nr_total_skips skipped)" fi if test $tt_nr_total_fails -eq 0; then stamp="${tt_color_green}OK:${tt_color_off}" stats="$((tt_nr_total_tests - tt_nr_total_skips)) of $tt_nr_total_tests tests passed" test $tt_nr_total_tests -eq 1 && stats=$(echo "$stats" | sed 's/tests /test /') tt_message "$stamp $stats$skips" exit 0 else test $tt_nr_files -eq 1 && tt_message # separate from previous FAILED message stamp="${tt_color_red}FAIL:${tt_color_off}" stats="$tt_nr_total_fails of $tt_nr_total_tests tests failed" test $tt_nr_total_tests -eq 1 && stats=$(echo "$stats" | sed 's/tests /test /') tt_message "$stamp $stats$skips" # test $tt_test_file = 'test.md' && tt_message "-t ${tt_failed_range%,}" # dev helper exit 1 fi aureliojargas-clitest-8bdaae2/examples/000077500000000000000000000000001444513361400204025ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/examples/README.md000066400000000000000000000034101444513361400216570ustar00rootroot00000000000000# clitest Examples Here's some simple examples to show you how a test file looks like. ## Pure CLI Tests Take a look at the `.txt` files. They're just like a shell session snapshot. You have the `$ ` prompt, the command to be executed, and the results. ``` $ echo "Hello World" Hello World $ ``` To test these files, just call `clitest` with no options. ``` $ clitest intro.txt #1 echo "Hello World" #2 cd /tmp #3 pwd #4 cd "$OLDPWD" OK: 4 of 4 tests passed $ ``` ### Easily create your own test files: 1. Go to your terminal 2. Set your prompt accordingly: `PS1='$ '` 3. Type and run the desired commands 4. Copy & paste it all into a text file 5. Done ## Documentation Tests Now take a look at the `.md` files. They're normal Markdown documents (with titles, paragraphs, code blocks), created to be read by humans (after HTML conversion). Inside the code blocks there are examples of command lines and their results. `clitest` can extract and run these commands for you! Now you can guarantee that all your examples are correct. ``` $ clitest --prefix tab cut.md #1 echo "one:two:three:four:five:six" | cut -d : -f 1 #2 echo "one:two:three:four:five:six" | cut -d : -f 4 #3 echo "one:two:three:four:five:six" | cut -d : -f 1,4 #4 echo "one:two:three:four:five:six" | cut -d : -f 4,1 #5 echo "one:two:three:four:five:six" | cut -d : -f 1-4 #6 echo "one:two:three:four:five:six" | cut -d : -f 4- OK: 6 of 6 tests passed $ ``` Note that since the code blocks in these Markdown documents are prefixed by a tab, you must use the `--prefix` option. Even this `README.md` file you're reading is testable. No options needed, since the code blocks here do not use prefixes. ## Play Around Run the tests, change the expected output to force a test fail, use the `--list-run` option, ... aureliojargas-clitest-8bdaae2/examples/cut.md000066400000000000000000000016171444513361400215240ustar00rootroot00000000000000The numeric ranges of the Unix command "cut" ============================================ Use single numbers to extract one specific field: $ echo "one:two:three:four:five:six" | cut -d : -f 1 one $ echo "one:two:three:four:five:six" | cut -d : -f 4 four Use commas to inform more than one field: $ echo "one:two:three:four:five:six" | cut -d : -f 1,4 one:four Note that inverting the order will *not* invert the output: $ echo "one:two:three:four:five:six" | cut -d : -f 4,1 one:four Use an hyphen to inform a range of fields, from one to four: $ echo "one:two:three:four:five:six" | cut -d : -f 1-4 one:two:three:four If you omit the second range number, it matches until the last: $ echo "one:two:three:four:five:six" | cut -d : -f 4- four:five:six cut is cool, isn't it? > Note: To automatically test all the shell commands in this article, > just run: `clitest --prefix tab cut.md` aureliojargas-clitest-8bdaae2/examples/cut.txt000066400000000000000000000006031444513361400217350ustar00rootroot00000000000000$ echo "one:two:three:four:five:six" | cut -d : -f 1 one $ echo "one:two:three:four:five:six" | cut -d : -f 4 four $ echo "one:two:three:four:five:six" | cut -d : -f 1,4 one:four $ echo "one:two:three:four:five:six" | cut -d : -f 4,1 one:four $ echo "one:two:three:four:five:six" | cut -d : -f 1-4 one:two:three:four $ echo "one:two:three:four:five:six" | cut -d : -f 4- four:five:six $ aureliojargas-clitest-8bdaae2/examples/hello-world.txt000066400000000000000000000000431444513361400233700ustar00rootroot00000000000000$ echo "Hello World" Hello World $ aureliojargas-clitest-8bdaae2/examples/install-software.md000066400000000000000000000041161444513361400242240ustar00rootroot00000000000000# How to install txt2tags v2.6 > This file is an example of a technical “how to” document > that can also be automatically tested: > `clitest --prefix tab install-software.md` ## 1. Prepare First, move to the temporary directory, where we will download, extract and test the txt2tags package before installing it to the system. $ cd /tmp ## 2. Download Download the .tgz file for the version 2.6, directly from Google Code. $ url="https://fossies.org/linux/privat/txt2tags-2.6.tgz" $ curl -O -s -S "$url" ## 3. Verify Let's verify if the downloaded package is not corrupted, by checking the file size and the total number of files inside the tgz. $ du -h txt2tags-2.6.tgz 532K txt2tags-2.6.tgz $ tar tzf txt2tags-2.6.tgz | sed -n '$=' 545 > Note: Using `sed` to count lines because the output format of `wc -l` > differs between implementations, regarding leading blank spaces. ## 4. Extract Since the download is ok, now we can extract the package's files. If `tar` shows no message, it's because everything went fine and all the files were extracted. $ tar xzf txt2tags-2.6.tgz A new `txt2tags-2.6` directory was created. Let's enter into it and list the main files, just to be sure. $ cd txt2tags-2.6 $ ls -1F COPYING ChangeLog README doc/ extras/ po/ samples/ test/ txt2tags* ## 5. Test The main `txt2tags` file is executable? Python is installed? Python version is compatible with the program? So many questions... But a simple command answers them all. $ ./txt2tags -V txt2tags version 2.6 If the version was shown, it's a proof that the program was run successfully: Python is installed and it's compatible. ## 6. Install By default, the program is installed in the `~/bin` user directory. Usually this directory is already there, but let's play safe and create it if necessary. $ test -d ~/bin || mkdir ~/bin The install process itself is just a simple file copy. $ cp txt2tags ~/bin/ Now just a final test, executing the program directly from `~/bin`. $ ~/bin/txt2tags -V txt2tags version 2.6 Ok, we're done. aureliojargas-clitest-8bdaae2/examples/install-software.txt000066400000000000000000000014531444513361400244440ustar00rootroot00000000000000$ cd /tmp $ url="https://fossies.org/linux/privat/txt2tags-2.6.tgz" $ curl -O -s -S "$url" # download $ du -h txt2tags-2.6.tgz # verify size 532K txt2tags-2.6.tgz $ tar tzf txt2tags-2.6.tgz | sed -n '$=' # verify number of files 545 $ tar xzf txt2tags-2.6.tgz # extract $ cd txt2tags-2.6 $ ls -1F # list contents COPYING ChangeLog README doc/ extras/ po/ samples/ test/ txt2tags* $ ./txt2tags -V # test execution txt2tags version 2.6 $ test -d ~/bin || mkdir ~/bin # create folder if needed $ cp txt2tags ~/bin/ # install to user folder $ ~/bin/txt2tags -V # final test txt2tags version 2.6 $ aureliojargas-clitest-8bdaae2/examples/intro.txt000066400000000000000000000001071444513361400222740ustar00rootroot00000000000000$ echo "Hello World" Hello World $ cd /tmp $ pwd /tmp $ cd "$OLDPWD" $ aureliojargas-clitest-8bdaae2/examples/will-fail.txt000066400000000000000000000000421444513361400230170ustar00rootroot00000000000000$ echo "Hello World" Hola Mundo $ aureliojargas-clitest-8bdaae2/test.md000066400000000000000000001635361444513361400201030ustar00rootroot00000000000000# Test suite for clitest This is the test file for the `clitest` program. Yes, the program can test itself! This file runs all the files inside the `test` folder and checks the results. The command line options are also tested. Usage: ./clitest test.md ## Preparing Make sure we're on the same folder as `clitest`, since all the file paths here are relative, not absolute. ``` $ test -f ./clitest; echo $? 0 $ test -d ./test/; echo $? 0 $ ``` Set a default terminal width of 80 columns. It's used by separator lines. ``` $ shopt -u checkwinsize 2> /dev/null # bash: disable automatic check $ unset COLUMNS # mksh: first unset, then one can manually set it $ COLUMNS=80 $ export COLUMNS $ ``` Ok. Now the real tests begins. ## Variables are persistent between tests? ``` $ echo $COLUMNS 80 $ not_exported=1 $ echo $not_exported 1 $ echo $not_exported #=> 1 $ echo $not_exported #=> --regex ^1$ ``` ## Check the temporary dir creation ``` $ TMPDIR___SAVE="$TMPDIR" $ TMPDIR=/notfound $ export TMPDIR $ ./clitest test/ok-1.sh 2>&1 | grep ^clitest | sed 's/clitest\..*$/clitest.XXXXXX/' clitest: Error: cannot create temporary dir: /notfound/clitest.XXXXXX $ TMPDIR="$TMPDIR___SAVE" $ ``` ## I/O, file reading (message and exit code) Missing input file ``` $ ./clitest; echo $? clitest: Error: no test file informed (try --help) 2 $ ./clitest -- clitest: Error: no test file informed (try --help) $ ./clitest --list clitest: Error: no test file informed (try --help) $ ``` File not found ``` $ ./clitest notfound; echo $? clitest: Error: cannot read input file: notfound 2 $ ``` File is a directory ``` $ ./clitest . clitest: Error: input file is a directory: . $ ./clitest ./ clitest: Error: input file is a directory: ./ $ ./clitest /etc clitest: Error: input file is a directory: /etc $ ``` ## No test found (message and exit code) ``` $ ./clitest test/no-test-found.sh; echo $? clitest: Error: no test found in input file: test/no-test-found.sh 2 $ ./clitest test/empty-file.sh clitest: Error: no test found in input file: test/empty-file.sh $ ./clitest test/empty-prompt-file.sh clitest: Error: no test found in input file: test/empty-prompt-file.sh $ ./clitest test/empty-prompts-file.sh clitest: Error: no test found in input file: test/empty-prompts-file.sh $ ``` ## Option --version The exit code must always be zero. ``` $ ./clitest --version > /dev/null; echo $? 0 $ ``` Test the output text and the short option `-V`. ``` $ ./clitest --version clitest 0.5.0 $ ./clitest -V clitest 0.5.0 $ ``` ## Option --help Test the full help text contents and the exit code (zero). ``` $ ./clitest --help; echo $? Usage: clitest [options] Options: -1, --first Stop execution upon first failed test -l, --list List all the tests (no execution) -L, --list-run List all the tests with OK/FAIL status -t, --test RANGE Run specific tests, by number (1,2,4-7) -s, --skip RANGE Skip specific tests, by number (1,2,4-7) --pre-flight COMMAND Execute command before running the first test --post-flight COMMAND Execute command after running the last test -q, --quiet Quiet operation, no output shown -V, --version Show program version and exit Customization options: -P, --progress TYPE Set progress indicator: test, number, dot, none --color WHEN Set when to use colors: auto, always, never --diff-options OPTIONS Set diff command options (default: '-u') --inline-prefix PREFIX Set inline output prefix (default: '#=> ') --prefix PREFIX Set command line prefix (default: '') --prompt STRING Set prompt string (default: '$ ') See also: https://github.com/aureliojargas/clitest 0 $ ``` The short option `-h` is working? Testing just the first and last lines for brevity. ``` $ ./clitest -h | sed -n '1p; $p' Usage: clitest [options] See also: https://github.com/aureliojargas/clitest $ ``` ## Option --quiet and exit code ``` $ ./clitest -q test/ok-2.sh; echo $? 0 $ ./clitest --quiet test/ok-2.sh; echo $? 0 $ ./clitest --quiet test/ok-2.sh test/ok-2.sh; echo $? 0 $ ./clitest --quiet test/fail-2.sh; echo $? 1 $ ./clitest --quiet test/fail-2.sh test/fail-2.sh; echo $? 1 $ ./clitest --quiet test/ok-2.sh test/fail-2.sh; echo $? 1 $ ``` ## Option --quiet has no effect in error messages ``` $ ./clitest --quiet notfound clitest: Error: cannot read input file: notfound $ ``` ## Option --quiet has no effect in --debug ``` $ ./clitest --debug --quiet test/ok-1.sh | grep -o INPUT_LINE INPUT_LINE INPUT_LINE $ ``` ## Option --debug Tricky test file with: empty line, inline marker, tab, $, comment line, normal command, unclosed block. ``` $ ./clitest --debug test/option-debug.sh -------------------------------------------------------------------------------- -- INPUT_LINE[# Test file to be run with --debug] -- LINE_MISC[# Test file to be run with --debug] -------------------------------------------------------------------------------- -- INPUT_LINE[] -- LINE_MISC[] -------------------------------------------------------------------------------- -- INPUT_LINE[$ echo "tab+space " #=> tab+space ] -- LINE_CMD[$ echo "tab+space " #=> tab+space ] -- NEW_CMD[echo "tab+space " ] -- OK_INLINE[tab+space ] -- OK_TEXT[tab+space ] #1 echo "tab+space " -- EVAL[echo "tab+space " ] -- OUTPUT[tab+space ] -------------------------------------------------------------------------------- -- INPUT_LINE[$] -- LINE_$[$] -------------------------------------------------------------------------------- -- INPUT_LINE[# A comment line between command blocks] -- LINE_MISC[# A comment line between command blocks] -------------------------------------------------------------------------------- -- INPUT_LINE[$ echo "unclosed block"] -- LINE_CMD[$ echo "unclosed block"] -- NEW_CMD[echo "unclosed block"] -------------------------------------------------------------------------------- -- INPUT_LINE[unclosed block] -- LINE_MISC[unclosed block] -- OK_TEXT[unclosed block] -- LOOP_OUT[$tt_test_command=echo "unclosed block"] #2 echo "unclosed block" -- EVAL[echo "unclosed block"] -- OUTPUT[unclosed block] OK: 2 of 2 tests passed $ ``` ## Option --debug with colors - Separator line is cyan - `INPUT_LINE[...]` is cyan, others are normal color inside `[]` - `` must be green - `#=>` inline marker must be red This test forces `--color always` because normally the tests inside this file are not colored (output is not a terminal). Note that the escape character (`\033`) is removed to have only printable ASCII characters in the output. ``` $ ./clitest --debug --color always test/option-debug-color.sh | head -n 3 | tr -d '\033' [36m--------------------------------------------------------------------------------[m [36m-- INPUT_LINE[$ echo "tab " #=> tab ][m [36m-- LINE_CMD[[m$ echo "tab[32m[m" [31m#=> [mtab[32m[m[36m][m $ ``` In case of multiple `#=>`, only the last one should be red: ``` $ ./clitest --debug --color always test/inline-multiple-marker.sh | command grep LINE_CMD | tr -d '\033' [36m-- LINE_CMD[[m$ echo "a #=> b #=> c" #=> --lines 99 [31m#=> [m--lines 1[36m][m $ ``` ## Option --color Invalid value ``` $ ./clitest --color foo test/ok-1.sh; echo $? clitest: Error: invalid value 'foo' for --color. Use: auto, always or never. 2 $ ``` Color ON > Note that the escape character (`\033`) is removed to have only printable ASCII characters in the output. ``` $ ./clitest --color always test/ok-1.sh | tr -d '\033' #1 echo ok [32mOK:[m 1 of 1 test passed $ ./clitest --color yes test/ok-1.sh | tr -d '\033' #1 echo ok [32mOK:[m 1 of 1 test passed $ ``` Color OFF ``` $ ./clitest --color never test/ok-1.sh #1 echo ok OK: 1 of 1 test passed $ ./clitest --color no test/ok-1.sh #1 echo ok OK: 1 of 1 test passed $ ``` Color AUTO Inside this file, the output is not a terminal, so the default is no colored output. ``` $ ./clitest test/ok-1.sh #1 echo ok OK: 1 of 1 test passed $ ``` The real default `--color auto` cannot be tested here. Test it by hand at the command line. ## Option --list Listing a file with no tests ``` $ ./clitest --list test/empty-file.sh; echo $? clitest: Error: no test found in input file: test/empty-file.sh 2 $ ``` Normal results and exit code ``` $ ./clitest --list test/no-nl-command.sh; echo $? #1 printf 'ok\n' #2 printf 'fail' #3 printf 'ok\nok\nfail' #4 printf 'ok\n' #5 printf 'fail' #6 printf 'ok'; echo #7 printf 'ok' 0 $ ``` Short option `-l` ``` $ ./clitest -l test/no-nl-command.sh #1 printf 'ok\n' #2 printf 'fail' #3 printf 'ok\nok\nfail' #4 printf 'ok\n' #5 printf 'fail' #6 printf 'ok'; echo #7 printf 'ok' $ ``` Multifile and exit code ``` $ ./clitest --list test/no-nl-command.sh test/ok-1.sh; echo $? ---------------------------------------- test/no-nl-command.sh #1 printf 'ok\n' #2 printf 'fail' #3 printf 'ok\nok\nfail' #4 printf 'ok\n' #5 printf 'fail' #6 printf 'ok'; echo #7 printf 'ok' ---------------------------------------- test/ok-1.sh #8 echo ok 0 $ ``` ## Option --list-run Listing a file with no tests ``` $ ./clitest --list-run test/empty-file.sh; echo $? clitest: Error: no test found in input file: test/empty-file.sh 2 $ ``` Normal results (using colors) and exit code > Note that the escape character (`\033`) is removed to have only printable ASCII characters in the output. ``` $ ./clitest --list-run --color always test/no-nl-command.sh > /tmp/foo.txt; echo $? 1 $ cat /tmp/foo.txt | tr -d '\033' [32m#1 printf 'ok\n'[m [31m#2 printf 'fail'[m [31m#3 printf 'ok\nok\nfail'[m [32m#4 printf 'ok\n' [m [31m#5 printf 'fail' [m [32m#6 printf 'ok'; echo [m [32m#7 printf 'ok' [m $ rm /tmp/foo.txt $ ``` Normal results (no colors, use OK/FAIL column) and exit code ``` $ ./clitest --list-run test/no-nl-command.sh; echo $? #1 OK printf 'ok\n' #2 FAIL printf 'fail' #3 FAIL printf 'ok\nok\nfail' #4 OK printf 'ok\n' #5 FAIL printf 'fail' #6 OK printf 'ok'; echo #7 OK printf 'ok' 1 $ ``` Short option `-L` ``` $ ./clitest -L test/no-nl-command.sh #1 OK printf 'ok\n' #2 FAIL printf 'fail' #3 FAIL printf 'ok\nok\nfail' #4 OK printf 'ok\n' #5 FAIL printf 'fail' #6 OK printf 'ok'; echo #7 OK printf 'ok' $ ``` Multifile and exit code ``` $ ./clitest -L test/no-nl-command.sh test/ok-1.sh; echo $? ---------------------------------------- test/no-nl-command.sh #1 OK printf 'ok\n' #2 FAIL printf 'fail' #3 FAIL printf 'ok\nok\nfail' #4 OK printf 'ok\n' #5 FAIL printf 'fail' #6 OK printf 'ok'; echo #7 OK printf 'ok' ---------------------------------------- test/ok-1.sh #8 OK echo ok 1 $ ./clitest -L test/ok-1.sh; echo $? #1 OK echo ok 0 $ ``` ## Option --progress First, some invalid values: ``` $ ./clitest --progress test/ok-1.sh clitest: Error: no test file informed (try --help) $ ./clitest --progress '' test/ok-1.sh clitest: Error: invalid value '' for --progress. Use: test, number, dot or none. $ ./clitest --progress foo test/ok-1.sh clitest: Error: invalid value 'foo' for --progress. Use: test, number, dot or none. $ ./clitest --progress DOT test/ok-1.sh clitest: Error: invalid value 'DOT' for --progress. Use: test, number, dot or none. $ ./clitest --progress @@ test/ok-1.sh clitest: Error: invalid value '@@' for --progress. Use: test, number, dot or none. $ ./clitest --progress -1 test/ok-1.sh; echo $? clitest: Error: invalid value '-1' for --progress. Use: test, number, dot or none. 2 $ ``` If no `--progress` option, defaults to `--progress test`: ``` $ ./clitest test/ok-1.sh #1 echo ok OK: 1 of 1 test passed $ ./clitest --progress test test/ok-1.sh #1 echo ok OK: 1 of 1 test passed $ ``` Numbers: ``` $ ./clitest --progress number test/ok-10.sh 1 2 3 4 5 6 7 8 9 10 OK: 10 of 10 tests passed $ ./clitest --progress n test/ok-10.sh 1 2 3 4 5 6 7 8 9 10 OK: 10 of 10 tests passed $ ./clitest --progress 0 test/ok-10.sh 1 2 3 4 5 6 7 8 9 10 OK: 10 of 10 tests passed $ ./clitest --progress 5 test/ok-10.sh 1 2 3 4 5 6 7 8 9 10 OK: 10 of 10 tests passed $ ./clitest --progress 9 test/ok-10.sh 1 2 3 4 5 6 7 8 9 10 OK: 10 of 10 tests passed $ ``` Chars: ``` $ ./clitest --progress dot test/ok-10.sh .......... OK: 10 of 10 tests passed $ ./clitest --progress . test/ok-10.sh .......... OK: 10 of 10 tests passed $ ./clitest --progress @ test/ok-10.sh @@@@@@@@@@ OK: 10 of 10 tests passed $ ./clitest --progress x test/ok-10.sh xxxxxxxxxx OK: 10 of 10 tests passed $ ``` No progress: ``` $ ./clitest --progress none test/ok-1.sh OK: 1 of 1 test passed $ ./clitest --progress no test/ok-1.sh OK: 1 of 1 test passed $ ``` Short option `-P`: ``` $ ./clitest -P dot test/ok-1.sh . OK: 1 of 1 test passed $ ./clitest -P no test/ok-1.sh OK: 1 of 1 test passed $ ``` Ok & fail functionality with dot: ``` $ ./clitest --progress . test/ok-1.sh . OK: 1 of 1 test passed $ ./clitest --progress . test/ok-2.sh .. OK: 2 of 2 tests passed $ ./clitest --progress . test/ok-50.sh .................................................. OK: 50 of 50 tests passed $ ./clitest --progress . test/fail-1.sh . -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- FAIL: 1 of 1 test failed $ ``` Multifile with dot: ``` $ ./clitest --progress . test/ok-1.sh test/ok-2.sh test/ok-10.sh Testing file test/ok-1.sh . Testing file test/ok-2.sh .. Testing file test/ok-10.sh .......... ok fail skip 1 - - test/ok-1.sh 2 - - test/ok-2.sh 10 - - test/ok-10.sh OK: 13 of 13 tests passed $ ./clitest --progress . test/ok-1.sh test/fail-1.sh Testing file test/ok-1.sh . Testing file test/fail-1.sh . -------------------------------------------------------------------------------- [FAILED #2, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- ok fail skip 1 - - test/ok-1.sh - 1 - test/fail-1.sh FAIL: 1 of 2 tests failed $ ./clitest --progress . test/fail-1.sh test/ok-1.sh Testing file test/fail-1.sh . -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- Testing file test/ok-1.sh . ok fail skip - 1 - test/fail-1.sh 1 - - test/ok-1.sh FAIL: 1 of 2 tests failed $ ``` Multifile with no progress: ``` $ ./clitest --progress none test/ok-1.sh test/ok-2.sh test/ok-10.sh Testing file test/ok-1.sh Testing file test/ok-2.sh Testing file test/ok-10.sh ok fail skip 1 - - test/ok-1.sh 2 - - test/ok-2.sh 10 - - test/ok-10.sh OK: 13 of 13 tests passed $ ./clitest --progress none test/ok-1.sh test/fail-1.sh Testing file test/ok-1.sh Testing file test/fail-1.sh -------------------------------------------------------------------------------- [FAILED #2, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- ok fail skip 1 - - test/ok-1.sh - 1 - test/fail-1.sh FAIL: 1 of 2 tests failed $ ./clitest --progress none test/fail-1.sh test/ok-1.sh Testing file test/fail-1.sh -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- Testing file test/ok-1.sh ok fail skip - 1 - test/fail-1.sh 1 - - test/ok-1.sh FAIL: 1 of 2 tests failed $ ``` ### Option --progress and skipped tests Since skipped tests affect the output (show nothing), it's worth testing if the line break issues won't appear. ``` $ ./clitest --progress . --skip 1 test/ok-2.sh . OK: 1 of 2 tests passed (1 skipped) $ ./clitest --progress . --skip 2 test/ok-2.sh . OK: 1 of 2 tests passed (1 skipped) $ ./clitest --progress . --skip 1 test/fail-2.sh . -------------------------------------------------------------------------------- [FAILED #2, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- FAIL: 1 of 2 tests failed (1 skipped) $ ./clitest --progress . --skip 2 test/fail-2.sh . -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- FAIL: 1 of 2 tests failed (1 skipped) $ ``` Error messages appear with no leading blank line? ``` $ ./clitest --progress . --skip 1,2 test/ok-2.sh clitest: Error: no test found. Maybe '--skip 1,2' was too much? $ ``` ## Options --quiet, --progress, --list and --list-run are mutually exclusive * Only one can be active, the others must be off. * The last informed will be the one used. ``` $ ./clitest --list --quiet test/ok-1.sh $ ./clitest --list-run --quiet test/ok-1.sh $ ./clitest --progress . --quiet test/ok-1.sh $ ./clitest --list --list-run --progress . --quiet test/ok-1.sh $ ./clitest --quiet --progress . --list-run --list test/ok-1.sh #1 echo ok $ ./clitest --quiet --progress . --list --list-run test/ok-1.sh #1 OK echo ok $ ./clitest --quiet --list --list-run --progress . test/ok-1.sh . OK: 1 of 1 test passed $ ``` ## Option --test and --skip combined with --list and --list-run Error: Out of range ``` $ ./clitest --list -t 99 test/ok-10.sh clitest: Error: no test found for the specified number or range '99' $ ./clitest --list-run -t 99 test/ok-10.sh; echo $? clitest: Error: no test found for the specified number or range '99' 2 $ ``` Error: Skipped all tests ``` $ ./clitest --list -s 1-10 test/ok-10.sh clitest: Error: no test found. Maybe '--skip 1-10' was too much? $ ./clitest --list-run -s 1-10 test/ok-10.sh; echo $? clitest: Error: no test found. Maybe '--skip 1-10' was too much? 2 $ ``` Error: The combination of `-t` and `-s` resulted in no tests ``` $ ./clitest --list -t 9 -s 9 test/ok-10.sh clitest: Error: no test found. The combination of -t and -s resulted in no tests. $ ./clitest --list-run -t 9 -s 9 test/ok-10.sh; echo $? clitest: Error: no test found. The combination of -t and -s resulted in no tests. 2 $ ``` Using `-t` alone ``` $ ./clitest --list -t 3,5-7 test/ok-10.sh #3 echo 3 #5 echo 5 #6 echo 6 #7 echo 7 $ ./clitest --list-run -t 3,5-7 test/ok-10.sh #3 OK echo 3 #5 OK echo 5 #6 OK echo 6 #7 OK echo 7 $ ``` Reverse ranges and repeated numbers are supported ``` $ ./clitest --list -t 3,7-5,3,6,5 test/ok-10.sh #3 echo 3 #5 echo 5 #6 echo 6 #7 echo 7 $ ``` Using `-t` to limit to a range and the `-s` exclude some more ``` $ ./clitest --list -t 3,5-7 -s 6 test/ok-10.sh #3 echo 3 #5 echo 5 #7 echo 7 $ ./clitest --list-run -t 3,5-7 -s 6 test/ok-10.sh #3 OK echo 3 #5 OK echo 5 #7 OK echo 7 $ ``` Multifile, using `-t` alone ``` $ ./clitest --list -t 1,3,5-7 test/ok-1.sh test/fail-2.sh test/ok-10.sh ---------------------------------------- test/ok-1.sh #1 echo ok ---------------------------------------- test/fail-2.sh #3 echo ok ---------------------------------------- test/ok-10.sh #5 echo 2 #6 echo 3 #7 echo 4 $ ./clitest --list-run -t 1,3,5-7 test/ok-1.sh test/fail-2.sh test/ok-10.sh ---------------------------------------- test/ok-1.sh #1 OK echo ok ---------------------------------------- test/fail-2.sh #3 FAIL echo ok ---------------------------------------- test/ok-10.sh #5 OK echo 2 #6 OK echo 3 #7 OK echo 4 $ ``` Multifile, using `-t` and `-s` ``` $ ./clitest --list -t 1,3,5-7 -s 3,6 test/ok-1.sh test/fail-2.sh test/ok-10.sh ---------------------------------------- test/ok-1.sh #1 echo ok ---------------------------------------- test/fail-2.sh ---------------------------------------- test/ok-10.sh #5 echo 2 #7 echo 4 $ ./clitest --list-run -t 1,3,5-7 -s 3,6 test/ok-1.sh test/fail-2.sh test/ok-10.sh ---------------------------------------- test/ok-1.sh #1 OK echo ok ---------------------------------------- test/fail-2.sh ---------------------------------------- test/ok-10.sh #5 OK echo 2 #7 OK echo 4 $ ``` ## Single file, OK ``` $ ./clitest test/ok-1.sh #1 echo ok OK: 1 of 1 test passed $ ./clitest test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ./clitest test/ok-50.sh | tail -1 OK: 50 of 50 tests passed $ ./clitest test/ok-100.sh | tail -1 OK: 100 of 100 tests passed $ ./clitest test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ``` ## Multifile, all OK ``` $ ./clitest test/ok-2.sh test/ok-2.sh Testing file test/ok-2.sh #1 echo ok #2 echo ok Testing file test/ok-2.sh #3 echo ok #4 echo ok ok fail skip 2 - - test/ok-2.sh 2 - - test/ok-2.sh OK: 4 of 4 tests passed $ ./clitest test/ok-1.sh test/ok-10.sh test/ok-100.sh test/ok-50.sh | grep -v ^# Testing file test/ok-1.sh Testing file test/ok-10.sh Testing file test/ok-100.sh Testing file test/ok-50.sh ok fail skip 1 - - test/ok-1.sh 10 - - test/ok-10.sh 100 - - test/ok-100.sh 50 - - test/ok-50.sh OK: 161 of 161 tests passed $ ./clitest test/ok-?.sh test/ok-10.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh #2 echo ok #3 echo ok Testing file test/ok-10.sh #4 echo 1 #5 echo 2 #6 echo 3 #7 echo 4 #8 echo 5 #9 echo 6 #10 echo 7 #11 echo 8 #12 echo 9 #13 echo 10 ok fail skip 1 - - test/ok-1.sh 2 - - test/ok-2.sh 10 - - test/ok-10.sh OK: 13 of 13 tests passed $ ``` ## Multifile, OK and fail ``` $ ./clitest test/ok-1.sh test/fail-1.sh test/ok-2.sh test/fail-2.sh Testing file test/ok-1.sh #1 echo ok Testing file test/fail-1.sh #2 echo ok -------------------------------------------------------------------------------- [FAILED #2, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- Testing file test/ok-2.sh #3 echo ok #4 echo ok Testing file test/fail-2.sh #5 echo ok -------------------------------------------------------------------------------- [FAILED #5, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- #6 echo ok -------------------------------------------------------------------------------- [FAILED #6, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- ok fail skip 1 - - test/ok-1.sh - 1 - test/fail-1.sh 2 - - test/ok-2.sh - 2 - test/fail-2.sh FAIL: 3 of 6 tests failed $ ./clitest test/ok-1.sh test/fail-1.sh test/ok-2.sh test/fail-2.sh Testing file test/ok-1.sh #1 echo ok Testing file test/fail-1.sh #2 echo ok -------------------------------------------------------------------------------- [FAILED #2, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- Testing file test/ok-2.sh #3 echo ok #4 echo ok Testing file test/fail-2.sh #5 echo ok -------------------------------------------------------------------------------- [FAILED #5, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- #6 echo ok -------------------------------------------------------------------------------- [FAILED #6, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- ok fail skip 1 - - test/ok-1.sh - 1 - test/fail-1.sh 2 - - test/ok-2.sh - 2 - test/fail-2.sh FAIL: 3 of 6 tests failed $ ``` ## Fail messages ``` $ ./clitest --prefix tab -P none test/fail-messages.md #=> --file test/fail-messages.out.txt $ ``` ## Fails ``` $ ./clitest test/fail-1.sh #1 echo ok -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- FAIL: 1 of 1 test failed $ ./clitest test/fail-2.sh #1 echo ok -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- #2 echo ok -------------------------------------------------------------------------------- [FAILED #2, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- FAIL: 2 of 2 tests failed $ ./clitest test/fail-50.sh | tail -1 FAIL: 50 of 50 tests failed $ ./clitest -1 test/fail-2.sh #1 echo ok -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- $ ./clitest --first test/fail-2.sh #1 echo ok -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- $ ./clitest --first test/fail-2.sh #1 echo ok -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- $ ./clitest test/fail-2.sh #1 echo ok -------------------------------------------------------------------------------- [FAILED #1, line 1] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- #2 echo ok -------------------------------------------------------------------------------- [FAILED #2, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- FAIL: 2 of 2 tests failed $ ``` ## Inline output with #=> ``` $ ./clitest test/inline.sh #1 echo 'one space' #2 echo 'one tab' #3 echo 'multi spaces' #4 echo 'multi tabs' #5 echo 'mixed' #6 echo ' leading space' #7 echo ' leading spaces' #8 printf '\tleading tab\n' #9 printf '\t\tleading tabs\n' #10 echo 'trailing space ' #11 echo 'trailing spaces ' #12 printf 'trailing tab\t\n' #13 printf 'trailing tabs\t\t\n' #14 echo ' ' #15 echo ' ' #16 printf '\t\n' #17 printf '\t\t\t\n' #18 printf ' \t \t\t \n' #19 echo "both inline and normal output" OK: 19 of 19 tests passed $ ``` In case of multiple `#=>`, consider only the last one: ``` $ ./clitest test/inline-multiple-marker.sh #1 echo "a #=> b #=> c" #=> --lines 99 OK: 1 of 1 test passed $ ## Inline match modes Mode #=> --text * This is the default mode. * The --text part can be omitted. ``` $ ./clitest --list-run test/inline-match-text.sh #1 OK echo 'abc' #2 OK echo 'abc' #3 OK printf '%s\n' '\t' #4 OK printf '%s\n' '\n' #5 OK echo '$PWD' #6 OK echo '$(date)' #7 OK echo '$' #8 OK echo '>' #9 OK echo '?' #10 OK echo '!' #11 OK echo '*' #12 OK echo '[' #13 OK echo '(' #14 OK echo #15 OK echo "not inline output" #=> #16 OK echo '123456789' #17 OK echo '1 3 7 9' #18 OK echo ' 5 ' #19 OK echo ' leading space' #20 OK echo ' leading spaces' #21 OK printf '\tleading tab\n' #22 OK printf '\t\tleading tabs\n' #23 OK echo 'trailing space ' #24 OK echo 'trailing spaces ' #25 OK printf 'trailing tab\t\n' #26 OK printf 'trailing tabs\t\t\n' #27 OK echo ' ' #28 FAIL echo ' ' #29 OK printf '\t\n' #30 OK printf '\t\t\t\n' #31 OK printf ' \t \t\t \n' #32 OK printf 'ok\n' #33 FAIL printf 'fail' #34 OK printf 'ok'; echo #35 FAIL echo 'fail' #36 FAIL echo 'fail' #37 OK echo ' ok' #38 OK echo '--text' #39 OK echo '--textual' #40 OK echo '--text is cool' $ ``` Mode #=> --eval ``` $ ./clitest --list-run test/inline-match-eval.sh #1 OK folder=$(pwd) #2 OK echo $folder #3 OK var='abc' #4 OK echo abc #5 OK echo 4 #6 OK today=$(date +%D) #7 OK echo "Today is $today" #8 OK printf 'ok' #9 OK echo ' leading space' #10 OK echo ' leading spaces' #11 OK printf '\tleading tab\n' #12 OK printf '\t\tleading tabs\n' #13 OK echo 'trailing space ' #14 OK echo 'trailing spaces ' #15 OK printf 'trailing tab\t\n' #16 OK printf 'trailing tabs\t\t\n' #17 OK echo ' ' #18 OK echo ' ' #19 OK printf '\t\n' #20 OK printf '\t\t\t\n' #21 OK printf ' \t \t\t \n' #22 FAIL echo 'fail' #23 FAIL echo 'fail' #24 OK echo '--eval' #25 OK echo '--evaluate' #26 OK echo '--eval is evil' $ ``` Mode #=> --egrep ``` $ ./clitest --list-run test/inline-match-egrep.sh #1 OK echo 'abc123' #2 OK echo 'abc123' #3 OK echo 'abc123' #4 OK echo 'abc123' #5 OK echo 'abc123' #6 OK echo 'abc123' #7 OK echo 'abc123' #8 OK echo 'abc123' #9 OK echo 'abc 123' #10 OK echo ' ' #11 OK echo ' ' #12 OK printf '\t\n' #13 OK printf '\t\t\t\n' #14 OK printf ' \t \t\t \n' #15 OK printf 'will\tmatch' #16 FAIL printf 'will\nfail' #17 OK printf '1\n2\n3\n4\nok\n' #18 OK printf 'ok' #19 OK printf 'ok\n' #20 FAIL echo 'fail' #21 FAIL echo 'fail' #22 OK echo ' ok' #23 OK echo '--egrep' #24 OK echo '--egreppal' #25 OK echo '--egrep is cool' $ ``` Mode #=> --perl * --regex is an alias to --perl ``` $ ./clitest --list-run test/inline-match-perl.sh #1 OK echo 'abc123' #2 OK echo 'abc123' #3 OK echo 'abc123' #4 OK echo 'abc123' #5 OK echo 'abc123' #6 OK echo 'abc123' #7 OK echo 'abc123' #8 OK echo 'abc123' #9 OK echo 'abc 123' #10 OK echo ' ' #11 OK echo ' ' #12 OK printf '\t\n' #13 OK printf '\t\t\t\n' #14 OK printf ' \t \t\t \n' #15 OK echo '01/01/2013' #16 OK echo "won't fail" #17 OK printf 'will\tmatch' #18 OK printf 'will\tmatch' #19 OK printf 'will\tmatch' #20 FAIL printf 'will\nfail' #21 OK printf 'will\nmatch' #22 FAIL printf 'will\nfail' #23 OK printf 'will\nmatch' #24 FAIL printf 'will\nfail' #25 OK printf 'will\nmatch' #26 OK printf 'ok' #27 OK printf 'ok\n' #28 OK printf '1\n2\n3\n' #29 OK printf '1\n2\n3\n' #30 FAIL echo 'fail' #31 FAIL echo 'fail' #32 OK echo ' ok' #33 OK echo '--perl' #34 OK echo '--perlism' #35 OK echo '--perl is cool' $ ``` Mode #=> --file ``` $ ./clitest --list-run test/inline-match-file.sh #1 OK printf '$ echo ok\nok\n' #2 OK echo 'ok' > /tmp/foo.txt #3 OK echo 'ok' #4 OK rm /tmp/foo.txt #5 FAIL echo 'fail' #6 FAIL echo 'fail' #7 OK echo '--file' #8 OK echo '--filer' #9 OK echo '--file is cool' $ ``` Mode #=> --lines ``` $ ./clitest --list-run test/inline-match-lines.sh #1 OK a=1 #2 OK echo 'ok' #3 OK printf '1\n2\n3\n' #4 OK printf 'no-nl' #5 OK printf '1\n2\nno-nl' #6 FAIL echo 'fail' #7 FAIL echo 'fail' #8 FAIL echo 'fail' #9 FAIL echo 'fail' #10 OK echo '--lines' #11 OK echo '--linesout' #12 OK echo '--lines is cool' $ ./clitest --first test/inline-match-lines.sh #1 a=1 #2 echo 'ok' #3 printf '1\n2\n3\n' #4 printf 'no-nl' #5 printf '1\n2\nno-nl' #6 echo 'fail' -------------------------------------------------------------------------------- [FAILED #6, line 16] echo 'fail' Expected 99 lines, got 1. -------------------------------------------------------------------------------- $ ``` Mode #=> --exit ``` $ ./clitest --list-run test/inline-match-exit.sh #1 OK true #2 OK false #3 OK sh -c 'exit 3' #4 OK command-not-found #5 OK echo "STDOUT ignored" #6 OK cut #7 OK echo "STDOUT ignored" #8 OK cut #9 FAIL echo 'fail' #10 FAIL echo 'fail' #11 FAIL echo 'fail' #12 OK echo '--exit' #13 OK echo '--exitout' #14 OK echo '--exit is cool' $ ./clitest --first test/inline-match-exit.sh #1 true #2 false #3 sh -c 'exit 3' #4 command-not-found #5 echo "STDOUT ignored" #6 cut #7 echo "STDOUT ignored" #8 cut #9 echo 'fail' -------------------------------------------------------------------------------- [FAILED #9, line 25] echo 'fail' Expected exit code 99, got 0 -------------------------------------------------------------------------------- $ ``` Errors for #=> --egrep ``` $ ./clitest test/inline-match-egrep-error-1.sh; echo $? clitest: Error: empty --egrep at line 1 of test/inline-match-egrep-error-1.sh 2 $ ./clitest test/inline-match-egrep-error-2.sh 2>&1 | sed 's/^e*grep: .*/egrep: ERROR_MSG/' #1 echo "error: malformed regex" egrep: ERROR_MSG clitest: Error: check your inline egrep regex at line 1 of test/inline-match-egrep-error-2.sh $ ``` Errors for #=> --perl (and --regex) ``` $ ./clitest test/inline-match-perl-error-1.sh; echo $? clitest: Error: empty --perl at line 1 of test/inline-match-perl-error-1.sh 2 $ ./clitest test/inline-match-perl-error-2.sh #1 echo "error: malformed regex" Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE / at -e line 1. clitest: Error: check your inline Perl regex at line 1 of test/inline-match-perl-error-2.sh $ ``` Errors for #=> --file ``` $ ./clitest test/inline-match-file-error-1.sh; echo $? clitest: Error: empty --file at line 1 of test/inline-match-file-error-1.sh 2 $ ./clitest test/inline-match-file-error-2.sh; echo $? #1 echo "error: file not found" clitest: Error: cannot read inline output file 'test/notfound', from line 1 of test/inline-match-file-error-2.sh 2 $ ./clitest test/inline-match-file-error-3.sh; echo $? #1 echo "error: directory" clitest: Error: cannot read inline output file '/etc/', from line 1 of test/inline-match-file-error-3.sh 2 $ ``` Errors for #=> --lines ``` $ ./clitest test/inline-match-lines-error-1.sh clitest: Error: --lines requires a number. See line 1 of test/inline-match-lines-error-1.sh $ ./clitest test/inline-match-lines-error-2.sh clitest: Error: --lines requires a number. See line 1 of test/inline-match-lines-error-2.sh $ ./clitest test/inline-match-lines-error-3.sh clitest: Error: --lines requires a number. See line 1 of test/inline-match-lines-error-3.sh $ ./clitest test/inline-match-lines-error-4.sh; echo $? clitest: Error: --lines requires a number. See line 1 of test/inline-match-lines-error-4.sh 2 $ ``` Errors for #=> --exit ``` $ ./clitest test/inline-match-exit-error-1.sh clitest: Error: --exit requires a number. See line 1 of test/inline-match-exit-error-1.sh $ ./clitest test/inline-match-exit-error-2.sh clitest: Error: --exit requires a number. See line 1 of test/inline-match-exit-error-2.sh $ ./clitest test/inline-match-exit-error-3.sh clitest: Error: --exit requires a number. See line 1 of test/inline-match-exit-error-3.sh $ ./clitest test/inline-match-exit-error-4.sh; echo $? clitest: Error: --exit requires a number. See line 1 of test/inline-match-exit-error-4.sh 2 $ ``` Errors for #=> --eval ``` $ ./clitest test/inline-match-eval-error-1.sh; echo $? clitest: Error: empty --eval at line 1 of test/inline-match-eval-error-1.sh 2 $ ``` ## Option -t, --test Error: Invalid argument ``` $ ./clitest -t - test/ok-2.sh clitest: Error: invalid argument for -t or --test: - $ ./clitest -t -1 test/ok-2.sh clitest: Error: invalid argument for -t or --test: -1 $ ./clitest -t 1- test/ok-2.sh clitest: Error: invalid argument for -t or --test: 1- $ ./clitest -t 1--2 test/ok-2.sh clitest: Error: invalid argument for -t or --test: 1--2 $ ./clitest -t 1-2-3 test/ok-2.sh; echo $? clitest: Error: invalid argument for -t or --test: 1-2-3 2 $ ``` Error: Out of range ``` $ ./clitest -t 99 test/ok-2.sh; echo $? clitest: Error: no test found for the specified number or range '99' 2 $ ``` If range = zero or empty, run all tests ``` $ ./clitest -t '' test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ./clitest -t 0 test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ``` * Empty values inside range are ignored * The bogus `0-0` range is ignored * The resulting range is zero ``` $ ./clitest -t ,,,0,0-0,,, test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ``` Normal operation, using `--test` and `-t` ``` $ ./clitest -t 1 test/ok-10.sh #1 echo 1 OK: 1 of 10 tests passed (9 skipped) $ ./clitest --test 1 test/ok-10.sh #1 echo 1 OK: 1 of 10 tests passed (9 skipped) $ ``` Ranges `0-1` and `1-0` expand to `1` ``` $ ./clitest -t 0-1,1-0 test/ok-10.sh #1 echo 1 OK: 1 of 10 tests passed (9 skipped) $ ``` Range `1-1` expand to `1` ``` $ ./clitest -t 1-1 test/ok-10.sh #1 echo 1 OK: 1 of 10 tests passed (9 skipped) $ ``` Repeated values are OK ``` $ ./clitest -t 1,1,1,0,1 test/ok-10.sh #1 echo 1 OK: 1 of 10 tests passed (9 skipped) $ ``` Range terminator is out of bounds ``` $ ./clitest -t 10-20 test/ok-10.sh #10 echo 10 OK: 1 of 10 tests passed (9 skipped) $ ``` Inverted ranges ``` $ ./clitest -t 3,2,1 test/ok-10.sh #1 echo 1 #2 echo 2 #3 echo 3 OK: 3 of 10 tests passed (7 skipped) $ ./clitest -t 3-1 test/ok-10.sh #1 echo 1 #2 echo 2 #3 echo 3 OK: 3 of 10 tests passed (7 skipped) $ ``` Multifile. The test numbers always increase sequentially, regardless of the file changes. ``` $ ./clitest -t 1,5,13 test/ok-?.sh test/ok-10.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh Testing file test/ok-10.sh #5 echo 2 #13 echo 10 ok fail skip 1 - - test/ok-1.sh - - 2 test/ok-2.sh 2 - 8 test/ok-10.sh OK: 3 of 13 tests passed (10 skipped) $ ./clitest -t 1,5 test/ok-[12].sh test/fail-2.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh Testing file test/fail-2.sh #5 echo ok -------------------------------------------------------------------------------- [FAILED #5, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- ok fail skip 1 - - test/ok-1.sh - - 2 test/ok-2.sh - 1 1 test/fail-2.sh FAIL: 1 of 5 tests failed (3 skipped) $ ./clitest -t 1 test/ok-[12].sh test/fail-2.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh Testing file test/fail-2.sh ok fail skip 1 - - test/ok-1.sh - - 2 test/ok-2.sh - - 2 test/fail-2.sh OK: 1 of 5 tests passed (4 skipped) $ ``` ## Option -s, --skip Error: Invalid argument ``` $ ./clitest -s - test/ok-2.sh clitest: Error: invalid argument for -s or --skip: - $ ./clitest -s -1 test/ok-2.sh clitest: Error: invalid argument for -s or --skip: -1 $ ./clitest -s 1- test/ok-2.sh clitest: Error: invalid argument for -s or --skip: 1- $ ./clitest -s 1--2 test/ok-2.sh clitest: Error: invalid argument for -s or --skip: 1--2 $ ./clitest -s 1-2-3 test/ok-2.sh; echo $? clitest: Error: invalid argument for -s or --skip: 1-2-3 2 $ ``` Error: Skipped all tests ``` $ ./clitest -s 1 test/ok-1.sh; echo $? clitest: Error: no test found. Maybe '--skip 1' was too much? 2 $ ``` Out of range: no problem, you just skipped a non-existent test. All tests will be run. ``` $ ./clitest -s 99 test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ``` If range = zero or empty, run all tests ``` $ ./clitest -s '' test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ./clitest -s 0 test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ``` * Empty values inside range are ignored * The bogus `0-0` range is ignored * The resulting range is zero ``` $ ./clitest -s ,,,0,0-0,,, test/ok-2.sh #1 echo ok #2 echo ok OK: 2 of 2 tests passed $ ``` Normal operation, using `--skip` and `-s` ``` $ ./clitest -s 1 test/ok-2.sh #2 echo ok OK: 1 of 2 tests passed (1 skipped) $ ./clitest --skip 1 test/ok-2.sh #2 echo ok OK: 1 of 2 tests passed (1 skipped) $ ``` Ranges `0-1` and `1-0` expand to `1` ``` $ ./clitest -s 0-1,1-0 test/ok-2.sh #2 echo ok OK: 1 of 2 tests passed (1 skipped) $ ``` Range `1-1` expand to `1` ``` $ ./clitest -s 1-1 test/ok-2.sh #2 echo ok OK: 1 of 2 tests passed (1 skipped) $ ``` Repeated values are OK ``` $ ./clitest -s 1,1,1,0,1 test/ok-2.sh #2 echo ok OK: 1 of 2 tests passed (1 skipped) $ ``` Range terminator is out of bounds ``` $ ./clitest -s 2-10 test/ok-2.sh #1 echo ok OK: 1 of 2 tests passed (1 skipped) $ ``` Inverted ranges ``` $ ./clitest -s 10,9,8,7,6,5,4 test/ok-10.sh #1 echo 1 #2 echo 2 #3 echo 3 OK: 3 of 10 tests passed (7 skipped) $ ./clitest -s 10-4 test/ok-10.sh #1 echo 1 #2 echo 2 #3 echo 3 OK: 3 of 10 tests passed (7 skipped) $ ``` Multifile. The test numbers always increase sequentially, regardless of the file changes. ``` $ ./clitest -s 2,3,13 test/ok-?.sh test/ok-10.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh Testing file test/ok-10.sh #4 echo 1 #5 echo 2 #6 echo 3 #7 echo 4 #8 echo 5 #9 echo 6 #10 echo 7 #11 echo 8 #12 echo 9 ok fail skip 1 - - test/ok-1.sh - - 2 test/ok-2.sh 9 - 1 test/ok-10.sh OK: 10 of 13 tests passed (3 skipped) $ ./clitest -s 2,3,4 test/ok-[12].sh test/fail-2.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh Testing file test/fail-2.sh #5 echo ok -------------------------------------------------------------------------------- [FAILED #5, line 3] echo ok @@ -1 +1 @@ -fail +ok -------------------------------------------------------------------------------- ok fail skip 1 - - test/ok-1.sh - - 2 test/ok-2.sh - 1 1 test/fail-2.sh FAIL: 1 of 5 tests failed (3 skipped) $ ./clitest -s 2-10 test/ok-[12].sh test/fail-2.sh Testing file test/ok-1.sh #1 echo ok Testing file test/ok-2.sh Testing file test/fail-2.sh ok fail skip 1 - - test/ok-1.sh - - 2 test/ok-2.sh - - 2 test/fail-2.sh OK: 1 of 5 tests passed (4 skipped) $ ``` ## Option --test combined with --skip Error: The combination of `-t` and `-s` resulted in no tests ``` $ ./clitest -t 9 -s 9 test/ok-10.sh; echo $? clitest: Error: no test found. The combination of -t and -s resulted in no tests. 2 $ ``` The order does not matter, `-s` always wins ``` $ ./clitest -s 9 -t 9 test/ok-10.sh clitest: Error: no test found. The combination of -t and -s resulted in no tests. $ ``` Using `-t` to limit to a range and the `-s` exclude some more ``` $ ./clitest -t 3,5-7 -s 6 test/ok-10.sh #3 echo 3 #5 echo 5 #7 echo 7 OK: 3 of 10 tests passed (7 skipped) $ ``` Same as previous, but now multifile ``` $ ./clitest -t 1,3,5-7 -s 3,6 test/ok-1.sh test/fail-2.sh test/ok-10.sh Testing file test/ok-1.sh #1 echo ok Testing file test/fail-2.sh Testing file test/ok-10.sh #5 echo 2 #7 echo 4 ok fail skip 1 - - test/ok-1.sh - - 2 test/fail-2.sh 2 - 8 test/ok-10.sh OK: 3 of 13 tests passed (10 skipped) $ ``` ## Option --diff-options ``` $ ./clitest test/option-diff-options.sh #1 echo " diff -w to ignore spaces " -------------------------------------------------------------------------------- [FAILED #1, line 3] echo " diff -w to ignore spaces " @@ -1 +1 @@ -diff -w to ignore spaces + diff -w to ignore spaces -------------------------------------------------------------------------------- #2 echo " diff -w now inline " -------------------------------------------------------------------------------- [FAILED #2, line 5] echo " diff -w now inline " @@ -1 +1 @@ -diff -w now inline + diff -w now inline -------------------------------------------------------------------------------- FAIL: 2 of 2 tests failed $ ./clitest --diff-options '-u -w' test/option-diff-options.sh #1 echo " diff -w to ignore spaces " #2 echo " diff -w now inline " OK: 2 of 2 tests passed $ ``` ## Option --prompt ``` $ ./clitest test/option-prompt.sh; echo $? clitest: Error: no test found in input file: test/option-prompt.sh 2 $ ./clitest --prompt 'prompt$ ' test/option-prompt.sh #1 echo "1" #2 echo "2" #3 echo "3" OK: 3 of 3 tests passed $ ./clitest --prompt '♥ ' test/option-prompt-unicode.sh #1 echo "1" #2 echo "2" #3 echo "3" OK: 3 of 3 tests passed $ ``` ## Option --inline-prefix ``` $ ./clitest test/option-inline-prefix.sh #1 echo "1 space" #==> 1 space -------------------------------------------------------------------------------- [FAILED #1, line 3] echo "1 space" #==> 1 space @@ -0,0 +1 @@ +1 space -------------------------------------------------------------------------------- #2 echo "8 spaces" #==> 8 spaces -------------------------------------------------------------------------------- [FAILED #2, line 4] echo "8 spaces" #==> 8 spaces @@ -0,0 +1 @@ +8 spaces -------------------------------------------------------------------------------- #3 echo "2 tabs" #==> 2 tabs -------------------------------------------------------------------------------- [FAILED #3, line 5] echo "2 tabs" #==> 2 tabs @@ -0,0 +1 @@ +2 tabs -------------------------------------------------------------------------------- FAIL: 3 of 3 tests failed $ ./clitest --inline-prefix '#==>' test/option-inline-prefix.sh #1 echo "1 space" -------------------------------------------------------------------------------- [FAILED #1, line 3] echo "1 space" @@ -1 +1 @@ - 1 space +1 space -------------------------------------------------------------------------------- #2 echo "8 spaces" -------------------------------------------------------------------------------- [FAILED #2, line 4] echo "8 spaces" @@ -1 +1 @@ - 8 spaces +8 spaces -------------------------------------------------------------------------------- #3 echo "2 tabs" -------------------------------------------------------------------------------- [FAILED #3, line 5] echo "2 tabs" @@ -1 +1 @@ - 2 tabs +2 tabs -------------------------------------------------------------------------------- FAIL: 3 of 3 tests failed $ ./clitest --inline-prefix '#==> ' test/option-inline-prefix.sh #1 echo "1 space" #2 echo "8 spaces" #3 echo "2 tabs" OK: 3 of 3 tests passed $ ``` ## Option --prefix ``` $ ./clitest --prefix ' ' test/option-prefix.sh #1 echo "1" #2 echo "2" #3 echo "3" #4 echo "4" #5 echo "5" #6 echo; echo "6"; echo; echo "7" OK: 6 of 6 tests passed $ ./clitest --prefix 4 test/option-prefix.sh #1 echo "1" #2 echo "2" #3 echo "3" #4 echo "4" #5 echo "5" #6 echo; echo "6"; echo; echo "7" OK: 6 of 6 tests passed $ ./clitest --prefix '\t' test/option-prefix-tab.sh #1 echo "1" #2 echo "2" #3 echo "3" #4 echo "4" #5 echo "5" #6 echo; echo "6"; echo; echo "7" OK: 6 of 6 tests passed $ ./clitest --prefix tab test/option-prefix-tab.sh #1 echo "1" #2 echo "2" #3 echo "3" #4 echo "4" #5 echo "5" #6 echo; echo "6"; echo; echo "7" OK: 6 of 6 tests passed $ ``` ## Option --prefix: glob gotchas ``` $ ./clitest --prefix '?' test/option-prefix-glob.sh #1 echo 'prefix ?' #2 echo 'prefix ?' OK: 2 of 2 tests passed $ ./clitest --prefix '*' test/option-prefix-glob.sh #1 echo 'prefix *' #2 echo 'prefix *' OK: 2 of 2 tests passed $ ./clitest --prefix '#' test/option-prefix-glob.sh #1 echo 'prefix #' #2 echo 'prefix #' OK: 2 of 2 tests passed $ ./clitest --prefix '%' test/option-prefix-glob.sh #1 echo 'prefix %' #2 echo 'prefix %' OK: 2 of 2 tests passed $ ./clitest --prefix '##' test/option-prefix-glob.sh #1 echo 'prefix ##' #2 echo 'prefix ##' OK: 2 of 2 tests passed $ ./clitest --prefix '%%' test/option-prefix-glob.sh #1 echo 'prefix %%' #2 echo 'prefix %%' OK: 2 of 2 tests passed $ ./clitest --prefix '#*' test/option-prefix-glob.sh #1 echo 'prefix #*' #2 echo 'prefix #*' OK: 2 of 2 tests passed $ ./clitest --prefix '*#' test/option-prefix-glob.sh #1 echo 'prefix *#' #2 echo 'prefix *#' OK: 2 of 2 tests passed $ ./clitest --prefix '%*' test/option-prefix-glob.sh #1 echo 'prefix %*' #2 echo 'prefix %*' OK: 2 of 2 tests passed $ ./clitest --prefix '*%' test/option-prefix-glob.sh #1 echo 'prefix *%' #2 echo 'prefix *%' OK: 2 of 2 tests passed $ ``` ## Option --prompt: glob gotchas (char + space) ``` $ ./clitest --prompt '? ' test/option-prompt-glob-space.sh #1 echo 'prompt ? ' #2 echo 'prompt ? ' OK: 2 of 2 tests passed $ ./clitest --prompt '* ' test/option-prompt-glob-space.sh #1 echo 'prompt * ' #2 echo 'prompt * ' OK: 2 of 2 tests passed $ ./clitest --prompt '# ' test/option-prompt-glob-space.sh #1 echo 'prompt # ' #2 echo 'prompt # ' OK: 2 of 2 tests passed $ ./clitest --prompt '% ' test/option-prompt-glob-space.sh #1 echo 'prompt % ' #2 echo 'prompt % ' OK: 2 of 2 tests passed $ ./clitest --prompt '## ' test/option-prompt-glob-space.sh #1 echo 'prompt ## ' #2 echo 'prompt ## ' OK: 2 of 2 tests passed $ ./clitest --prompt '%% ' test/option-prompt-glob-space.sh #1 echo 'prompt %% ' #2 echo 'prompt %% ' OK: 2 of 2 tests passed $ ./clitest --prompt '#* ' test/option-prompt-glob-space.sh #1 echo 'prompt #* ' #2 echo 'prompt #* ' OK: 2 of 2 tests passed $ ./clitest --prompt '*# ' test/option-prompt-glob-space.sh #1 echo 'prompt *# ' #2 echo 'prompt *# ' OK: 2 of 2 tests passed $ ./clitest --prompt '%* ' test/option-prompt-glob-space.sh #1 echo 'prompt %* ' #2 echo 'prompt %* ' OK: 2 of 2 tests passed $ ./clitest --prompt '*% ' test/option-prompt-glob-space.sh #1 echo 'prompt *% ' #2 echo 'prompt *% ' OK: 2 of 2 tests passed $ ``` ## Option --prompt: glob gotchas (chars only) ``` $ ./clitest --prompt '?' test/option-prompt-glob-1.sh #1 echo 'prompt ?' #2 echo 'prompt ?' OK: 2 of 2 tests passed $ ./clitest --prompt '*' test/option-prompt-glob-1.sh #1 echo 'prompt *' #2 echo 'prompt *' OK: 2 of 2 tests passed $ ./clitest --prompt '#' test/option-prompt-glob-1.sh #1 echo 'prompt #' #2 echo 'prompt #' OK: 2 of 2 tests passed $ ./clitest --prompt '%' test/option-prompt-glob-1.sh #1 echo 'prompt %' #2 echo 'prompt %' OK: 2 of 2 tests passed $ ./clitest --prompt '##' test/option-prompt-glob-2.sh #1 echo 'prompt ##' #2 echo 'prompt ##' OK: 2 of 2 tests passed $ ./clitest --prompt '%%' test/option-prompt-glob-2.sh #1 echo 'prompt %%' #2 echo 'prompt %%' OK: 2 of 2 tests passed $ ./clitest --prompt '#*' test/option-prompt-glob-2.sh #1 echo 'prompt #*' #2 echo 'prompt #*' OK: 2 of 2 tests passed $ ./clitest --prompt '*#' test/option-prompt-glob-2.sh #1 echo 'prompt *#' #2 echo 'prompt *#' OK: 2 of 2 tests passed $ ./clitest --prompt '%*' test/option-prompt-glob-2.sh #1 echo 'prompt %*' #2 echo 'prompt %*' OK: 2 of 2 tests passed $ ./clitest --prompt '*%' test/option-prompt-glob-2.sh #1 echo 'prompt *%' #2 echo 'prompt *%' OK: 2 of 2 tests passed $ ``` ## Options --pre-flight and --post-flight ``` $ ./clitest --pre-flight 'tt_test_number=99; tt_nr_total_tests=99' test/ok-1.sh #100 echo ok OK: 100 of 100 tests passed $ ./clitest --post-flight 'tt_nr_total_fails=50' test/ok-50.sh | tail -1 FAIL: 50 of 50 tests failed $ ./clitest --pre-flight 'false' test/ok-1.sh; echo $? clitest: Error: pre-flight command failed with status=1: false 2 $ ./clitest --post-flight 'false' test/ok-1.sh; echo $? #1 echo ok clitest: Error: post-flight command failed with status=1: false 2 $ ``` ## Invalid option ``` $ ./clitest --quiet --foo test/ok-1.sh clitest: Error: invalid option --foo $ ./clitest --first --foo test/ok-1.sh clitest: Error: invalid option --foo $ ./clitest --foo test/ok-1.sh clitest: Error: invalid option --foo $ ./clitest --foo clitest: Error: invalid option --foo $ ./clitest -Z; echo $? clitest: Error: invalid option -Z 2 $ ``` ## Options terminator -- ``` $ ./clitest -t 99 -- --quiet clitest: Error: cannot read input file: --quiet $ ``` ## File - meaning STDIN ``` $ cat test/ok-1.sh | ./clitest - #1 echo ok OK: 1 of 1 test passed $ cat test/ok-1.sh | ./clitest -- -; echo $? #1 echo ok OK: 1 of 1 test passed 0 $ ``` ## Read test file from /dev/stdin ``` $ cat test/ok-1.sh | ./clitest /dev/stdin #1 echo ok OK: 1 of 1 test passed $ ``` ## Test file is a symlink ``` $ ln -s test/ok-1.sh testsymlink $ ./clitest testsymlink #1 echo ok OK: 1 of 1 test passed $ rm testsymlink $ ``` ## Gotchas Test exit code and STDOUT/STDERR at the same time ``` $ ./clitest notfound; echo $? clitest: Error: cannot read input file: notfound 2 $ ./clitest test/exit-code-and-stdout.sh #1 echo "zero"; echo $? #2 echo "two"; sh -c "exit 2"; echo $? OK: 2 of 2 tests passed $ ``` STDIN and STDOUT ``` $ ./clitest test/stdout-stderr.sh #1 echo "stdout" #2 echo "stdout" 2> /dev/null #3 echo "stderr" 1>&2 #4 echo "stdout" > /dev/null #5 echo "stdout" 2> /dev/null 1>&2 #6 ./clitest notfound #7 ./clitest notfound > /dev/null #8 ./clitest notfound 2>&1 #9 ./clitest notfound 2> /dev/null #10 ./clitest notfound > /dev/null 2>&1 OK: 10 of 10 tests passed $ ``` STDIN Isolation ``` $ ./clitest --quiet test/stdin-isolation.sh ; echo $? 0 $ ``` Temporary files and directories must be removed after execution ``` $ TMPDIR__TEST=$(mktemp -d) $ TMPDIR="$TMPDIR__TEST" ./clitest --help >/dev/null 2>&1 $ find "$TMPDIR__TEST" -mindepth 1 $ echo '$ true' | TMPDIR="$TMPDIR__TEST" ./clitest --debug - >/dev/null 2>&1 $ find "$TMPDIR__TEST" -mindepth 1 $ unset TMPDIR__TEST $ ``` Multiple commands in one line ``` $ ./clitest test/multi-commands.sh #1 echo 1; echo 2; echo 3; echo 4; echo 5 #2 (echo 1; echo 2; echo 3; echo 4; echo 5) | sed -n 3p #3 (echo 1; echo 2; echo 3; echo 4; echo 5) | sed -n 3p OK: 3 of 3 tests passed $ ``` A `cd` command in one test should not affect the next ``` $ ./clitest test/cd.sh test/ok-2.sh Testing file test/cd.sh #1 cd Testing file test/ok-2.sh #2 echo ok #3 echo ok ok fail skip 1 - - test/cd.sh 2 - - test/ok-2.sh OK: 3 of 3 tests passed $ ``` Syntax: End-of-file or empty prompt closes the previous command ``` $ ./clitest test/close-command.sh #1 echo 1 #2 echo 2 #3 echo 3 OK: 3 of 3 tests passed $ ``` Windows files (CR+LF) ``` $ ./clitest test/windows.sh #1 echo "a file with CRLF line ending" #2 echo "inline output" #3 echo "inline regex" OK: 3 of 3 tests passed $ ``` Unicode chars ``` $ ./clitest test/special-chars.sh | tail -1 OK: 206 of 206 tests passed $ ``` Blanks (space, tab, newline) in the output ``` $ ./clitest test/blank-output.sh #1 echo ' ' #2 echo ' ' #3 printf '\t\n' #4 printf '\t\t\t\n' #5 printf ' \t \t\t \n' #6 printf '\n \n \n \n \n\n' #7 printf '\n\t\n\t\t\n\t\t\t\n\t\t\t\t\n\n' #8 printf '\n' #9 printf '\n\n' #10 printf '\n\n\n\n' OK: 10 of 10 tests passed $ ``` Files with no newline (`\n`) at the end 1. No empty prompt at the last line 2. Empty prompt at the last line 3. Inline output ``` $ ./clitest test/no-nl-file-1.sh #1 printf '%s\n' 'a file with no \n at the last line' OK: 1 of 1 test passed $ ./clitest test/no-nl-file-2.sh #1 printf '%s\n' 'another file with no \n at the last line' OK: 1 of 1 test passed $ ./clitest test/no-nl-file-3.sh #1 printf '%s\n' 'oneliner, no \n' OK: 1 of 1 test passed $ ``` Commands whose output has no `\n` ``` $ ./clitest test/no-nl-command.sh #1 printf 'ok\n' #2 printf 'fail' -------------------------------------------------------------------------------- [FAILED #2, line 6] printf 'fail' @@ -1 +1 @@ -fail +fail \ No newline at end of file -------------------------------------------------------------------------------- #3 printf 'ok\nok\nfail' -------------------------------------------------------------------------------- [FAILED #3, line 8] printf 'ok\nok\nfail' @@ -1,3 +1,3 @@ ok ok -fail +fail \ No newline at end of file -------------------------------------------------------------------------------- #4 printf 'ok\n' #5 printf 'fail' -------------------------------------------------------------------------------- [FAILED #5, line 17] printf 'fail' @@ -1 +1 @@ -fail +fail \ No newline at end of file -------------------------------------------------------------------------------- #6 printf 'ok'; echo #7 printf 'ok' FAIL: 3 of 7 tests failed $ ``` ## And now, the colored output tests > Note that the escape character (`\033`) is removed to have only printable ASCII characters in the output. ``` $ ./clitest --color yes --first test/fail-2.sh | tr -d '\033' #1 echo ok [31m--------------------------------------------------------------------------------[m [31m[FAILED #1, line 1] echo ok[m @@ -1 +1 @@ -fail +ok [31m--------------------------------------------------------------------------------[m $ ``` aureliojargas-clitest-8bdaae2/test/000077500000000000000000000000001444513361400175435ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/test/blank-output.sh000066400000000000000000000004271444513361400225270ustar00rootroot00000000000000$ echo ' ' $ echo ' ' $ printf '\t\n' $ printf '\t\t\t\n' $ printf ' \t \t\t \n' $ printf '\n \n \n \n \n\n' $ printf '\n\t\n\t\t\n\t\t\t\n\t\t\t\t\n\n' $ printf '\n' $ printf '\n\n' $ printf '\n\n\n\n' $ aureliojargas-clitest-8bdaae2/test/cd.sh000066400000000000000000000003451444513361400204670ustar00rootroot00000000000000# Some tests may change the current dir. # This could affect the next tests. # This could affect the relative path for the next input file. # To avoid problems, the current dir is always reset when a new test file is read. $ cd aureliojargas-clitest-8bdaae2/test/close-command.sh000066400000000000000000000004101444513361400226130ustar00rootroot00000000000000# Syntax: Empty prompt (with space) closes the previous command $ echo 1 1 $ # Syntax: Empty prompt (no space) closes the previous command $ echo 2 2 $ # Syntax: Repeated empty prompts are OK $ $ $ # Syntax: End-of-file closes the last command $ echo 3 3 aureliojargas-clitest-8bdaae2/test/empty-file.sh000066400000000000000000000000001444513361400221400ustar00rootroot00000000000000aureliojargas-clitest-8bdaae2/test/empty-prompt-file.sh000066400000000000000000000000031444513361400234620ustar00rootroot00000000000000$ aureliojargas-clitest-8bdaae2/test/empty-prompts-file.sh000066400000000000000000000000571444513361400236560ustar00rootroot00000000000000$ $ $ # Comment $ $ $ # Comment $ $ $ aureliojargas-clitest-8bdaae2/test/exit-code-and-stdout.sh000066400000000000000000000001141444513361400240340ustar00rootroot00000000000000$ echo "zero"; echo $? zero 0 $ echo "two"; sh -c "exit 2"; echo $? two 2 $ aureliojargas-clitest-8bdaae2/test/fail-1.sh000066400000000000000000000000171444513361400211460ustar00rootroot00000000000000$ echo ok fail aureliojargas-clitest-8bdaae2/test/fail-2.sh000066400000000000000000000000431444513361400211460ustar00rootroot00000000000000$ echo ok fail $ echo ok #=> fail aureliojargas-clitest-8bdaae2/test/fail-50.sh000066400000000000000000000016551444513361400212430ustar00rootroot00000000000000$ echo 1 #=> fail $ echo 2 #=> fail $ echo 3 #=> fail $ echo 4 #=> fail $ echo 5 #=> fail $ echo 6 #=> fail $ echo 7 #=> fail $ echo 8 #=> fail $ echo 9 #=> fail $ echo 10 #=> fail $ echo 11 #=> fail $ echo 12 #=> fail $ echo 13 #=> fail $ echo 14 #=> fail $ echo 15 #=> fail $ echo 16 #=> fail $ echo 17 #=> fail $ echo 18 #=> fail $ echo 19 #=> fail $ echo 20 #=> fail $ echo 21 #=> fail $ echo 22 #=> fail $ echo 23 #=> fail $ echo 24 #=> fail $ echo 25 #=> fail $ echo 26 #=> fail $ echo 27 #=> fail $ echo 28 #=> fail $ echo 29 #=> fail $ echo 30 #=> fail $ echo 31 #=> fail $ echo 32 #=> fail $ echo 33 #=> fail $ echo 34 #=> fail $ echo 35 #=> fail $ echo 36 #=> fail $ echo 37 #=> fail $ echo 38 #=> fail $ echo 39 #=> fail $ echo 40 #=> fail $ echo 41 #=> fail $ echo 42 #=> fail $ echo 43 #=> fail $ echo 44 #=> fail $ echo 45 #=> fail $ echo 46 #=> fail $ echo 47 #=> fail $ echo 48 #=> fail $ echo 49 #=> fail $ echo 50 #=> fail aureliojargas-clitest-8bdaae2/test/fail-messages.md000066400000000000000000000006551444513361400226130ustar00rootroot00000000000000# Fail Messages ## inline text $ echo fail #=> ok $ echo fail #=> --eval echo ok ## normal command $ echo fail ok $ echo fail ok 1 ok 2 ok 3 $ ## inline --file $ echo fail #=> --file lorem-ipsum.txt ## inline --lines $ echo fail #=> --lines 9 ## inline --egrep $ echo fail #=> --egrep ^[0-9]+$ ## inline --perl $ echo fail #=> --perl ^[0-9]+$ ## inline --regex $ echo fail #=> --regex ^[0-9]+$ aureliojargas-clitest-8bdaae2/test/fail-messages.out.txt000066400000000000000000000030761444513361400236400ustar00rootroot00000000000000-------------------------------------------------------------------------------- [FAILED #1, line 5] echo fail @@ -1 +1 @@ -ok +fail -------------------------------------------------------------------------------- [FAILED #2, line 6] echo fail @@ -1 +1 @@ -ok +fail -------------------------------------------------------------------------------- [FAILED #3, line 10] echo fail @@ -1 +1 @@ -ok +fail -------------------------------------------------------------------------------- [FAILED #4, line 12] echo fail @@ -1,3 +1 @@ -ok 1 -ok 2 -ok 3 +fail -------------------------------------------------------------------------------- [FAILED #5, line 20] echo fail @@ -1,5 +1 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. -Proin euismod blandit pharetra. -Vestibulum eu neque eget lorem gravida commodo a cursus massa. -Fusce sit amet lorem sem. -Donec eu quam leo. +fail -------------------------------------------------------------------------------- [FAILED #6, line 24] echo fail Expected 9 lines, got 1. -------------------------------------------------------------------------------- [FAILED #7, line 28] echo fail egrep '^[0-9]+$' failed in: fail -------------------------------------------------------------------------------- [FAILED #8, line 32] echo fail Perl regex '^[0-9]+$' not matched in: fail -------------------------------------------------------------------------------- [FAILED #9, line 36] echo fail Perl regex '^[0-9]+$' not matched in: fail -------------------------------------------------------------------------------- FAIL: 9 of 9 tests failed aureliojargas-clitest-8bdaae2/test/inline-match-egrep-error-1.sh000066400000000000000000000000521444513361400250310ustar00rootroot00000000000000$ echo 'error: no contents' #=> --egrep aureliojargas-clitest-8bdaae2/test/inline-match-egrep-error-2.sh000066400000000000000000000005131444513361400250340ustar00rootroot00000000000000$ echo "error: malformed regex" #=> --egrep ( # Some grep errors: # $ echo | egrep '(' ; echo $? # egrep: parentheses not balanced # 2 # $ echo | egrep '[' ; echo $? # egrep: brackets ([ ]) not balanced # 2 # $ echo | egrep '**' ; echo $? # egrep: repetition-operator operand invalid # 2 # $ echo | egrep '{' ; echo $? # 1 # $ aureliojargas-clitest-8bdaae2/test/inline-match-egrep.sh000066400000000000000000000061641444513361400235560ustar00rootroot00000000000000# Inline matching method: --egrep # Matches a egrep-style regular expression in the command output # # In fact, it's a real egrep match: eval $command | grep -E 'regex' # If grep matched, we have a successful test. That means that in # a multiline result, even if just a single line matches the regex, # the test is considered OK. # # Test your regexes with grep -E at the command line before adding # tests using them. # See man re_format in your system # http://www.freebsd.org/cgi/man.cgi?query=re_format&sektion=7 # Use anchors ^ and $ to match the full output text $ echo 'abc123' #=> --egrep ^abc123$ $ echo 'abc123' #=> --egrep ^abc.*3$ $ echo 'abc123' #=> --egrep ^abc[0-9]+$ # Omit one or both anchors to make a partial match $ echo 'abc123' #=> --egrep ^abc $ echo 'abc123' #=> --egrep 123$ $ echo 'abc123' #=> --egrep [0-9]+$ $ echo 'abc123' #=> --egrep bc $ echo 'abc123' #=> --egrep . # Blanks are preserved, no escaping or quoting needed $ echo 'abc 123' #=> --egrep ^abc [0-9]+$ # Blank output can also be matched # (there are literal tabs in some of those --egrep arguments) $ echo ' ' #=> --egrep ^ $ $ echo ' ' #=> --egrep ^ $ $ printf '\t\n' #=> --egrep ^ $ $ printf '\t\t\t\n' #=> --egrep ^ $ $ printf ' \t \t\t \n' #=> --egrep ^ $ # In some systems, the special sequence \t is expanded to a tab in # egrep regexes. In others, such as GNU grep >= 3.9, using \t (or \n) # won't work and warnings will be shown (see issue #53). # Use literal tabs to avoid problems. $ printf 'will\tmatch' #=> --egrep ^will match$ # Since it's an egrep test, regexes are not multiline. # You can only match a single line. # This test will fail: $ printf 'will\nfail' #=> --egrep will.*fail # If one line of a multiline results matches, the test is OK $ printf '1\n2\n3\n4\nok\n' #=> --egrep ok # As egrep is used for the test and it ignores the line break, # you can match both full (with \n) and partial (without \n). $ printf 'ok' #=> --egrep ok $ printf 'ok\n' #=> --egrep ok # Syntax: Must be exactly one space before and after --egrep $ echo 'fail' #=> --egrep fail with 2 spaces $ echo 'fail' #=> --egrep fail with tab # Syntax: The extra space after '--egrep ' is already part of the regex $ echo ' ok' #=> --egrep ok # Syntax: The space after --egrep is required. # When missing, the '--egrep' is considered a normal text. $ echo '--egrep' #=> --egrep # Syntax: Make sure we won't catch partial matches. $ echo '--egreppal' #=> --egreppal # Syntax: To insert a literal text that begins with '--egrep ' # just prefix it with --text. $ echo '--egrep is cool' #=> --text --egrep is cool # Syntax: Empty inline output contents are considered an error # Note: Tested in a separate file: inline-match-egrep-error-1.sh # # $ echo 'no contents' #=> --egrep aureliojargas-clitest-8bdaae2/test/inline-match-eval-error-1.sh000066400000000000000000000000511444513361400246550ustar00rootroot00000000000000$ echo 'error: no contents' #=> --eval aureliojargas-clitest-8bdaae2/test/inline-match-eval.sh000066400000000000000000000042451444513361400234010ustar00rootroot00000000000000# Inline matching method: --eval # Matches the text output from an arbitrary shell command # Run a simple command $ folder=$(pwd) $ echo $folder #=> --eval pwd # Read the contents of a variable $ var='abc' $ echo abc #=> --eval echo $var # Use arithmetic expansion $ echo 4 #=> --eval echo $((2+2)) # Run a subshell $ today=$(date +%D) $ echo "Today is $today" #=> --eval echo "Today is $(date +%D)" # You can also match lines without the final \n $ printf 'ok' #=> --eval printf 'ok' # Blanks are preserved $ echo ' leading space' #=> --eval echo ' leading space' $ echo ' leading spaces' #=> --eval echo ' leading spaces' $ printf '\tleading tab\n' #=> --eval printf '\tleading tab\n' $ printf '\t\tleading tabs\n' #=> --eval printf '\t\tleading tabs\n' $ echo 'trailing space ' #=> --eval echo 'trailing space ' $ echo 'trailing spaces ' #=> --eval echo 'trailing spaces ' $ printf 'trailing tab\t\n' #=> --eval printf 'trailing tab\t\n' $ printf 'trailing tabs\t\t\n' #=> --eval printf 'trailing tabs\t\t\n' $ echo ' ' #=> --eval echo ' ' $ echo ' ' #=> --eval echo ' ' $ printf '\t\n' #=> --eval printf '\t\n' $ printf '\t\t\t\n' #=> --eval printf '\t\t\t\n' $ printf ' \t \t\t \n' #=> --eval printf ' \t \t\t \n' # Syntax: Must be exactly one space before and after --eval $ echo 'fail' #=> --eval fail with 2 spaces $ echo 'fail' #=> --eval fail with tab # Syntax: The space after --eval is required. # When missing, the '--eval' is considered a normal text. $ echo '--eval' #=> --eval # Syntax: Make sure we won't catch partial matches. $ echo '--evaluate' #=> --evaluate # Syntax: To insert a literal text that begins with '--eval ' # just prefix it with --text. $ echo '--eval is evil' #=> --text --eval is evil # Syntax: Empty inline output contents are considered an error # Note: Tested in separate files: inline-match-eval-error-?.sh # # $ echo 'no contents' #=> --eval aureliojargas-clitest-8bdaae2/test/inline-match-exit-error-1.sh000066400000000000000000000000511444513361400246770ustar00rootroot00000000000000$ echo 'error: no contents' #=> --exit aureliojargas-clitest-8bdaae2/test/inline-match-exit-error-2.sh000066400000000000000000000000571444513361400247060ustar00rootroot00000000000000$ echo 'error: negative number' #=> --exit -1 aureliojargas-clitest-8bdaae2/test/inline-match-exit-error-3.sh000066400000000000000000000000551444513361400247050ustar00rootroot00000000000000$ echo 'error: float number' #=> --exit 1.0 aureliojargas-clitest-8bdaae2/test/inline-match-exit-error-4.sh000066400000000000000000000000551444513361400247060ustar00rootroot00000000000000$ echo 'error: not a number' #=> --exit foo aureliojargas-clitest-8bdaae2/test/inline-match-exit.sh000066400000000000000000000032551444513361400234230ustar00rootroot00000000000000# Inline matching method: --exit # Matches the test exit code. $ true #=> --exit 0 $ false #=> --exit 1 $ sh -c 'exit 3' #=> --exit 3 $ command-not-found #=> --exit 127 # STDIN and STDOUT are ignored when using --exit $ echo "STDOUT ignored" #=> --exit 0 This output will be ignored. $ cut #=> --exit 1 This output will be ignored. $ # You can also safely omit the output in the test file $ echo "STDOUT ignored" #=> --exit 0 $ cut #=> --exit 1 # The error message is a short sentence, not a diff # Example: Expected exit code 0, got 1. $ echo 'fail' #=> --exit 99 # Syntax: Must be exactly one space before and after --exit $ echo 'fail' #=> --exit fail with 2 spaces $ echo 'fail' #=> --exit fail with tab # Syntax: The space after --exit is required. # When missing, the '--exit' is considered a normal text. $ echo '--exit' #=> --exit # Syntax: Make sure we won't catch partial matches. $ echo '--exitout' #=> --exitout # Syntax: To insert a literal text that begins with '--exit ' # just prefix it with --text. $ echo '--exit is cool' #=> --text --exit is cool # Note: The following are tested in separate files: # inline-match-exit-error-?.sh # # Syntax: Empty inline output contents are considered an error # # $ echo 'no contents' #=> --exit # # Syntax: Must be an integer number # # $ echo 'fail' #=> --exit -1 # $ echo 'fail' #=> --exit 1.0 # $ echo 'fail' #=> --exit foo aureliojargas-clitest-8bdaae2/test/inline-match-file-error-1.sh000066400000000000000000000000511444513361400246450ustar00rootroot00000000000000$ echo 'error: no contents' #=> --file aureliojargas-clitest-8bdaae2/test/inline-match-file-error-2.sh000066400000000000000000000000641444513361400246520ustar00rootroot00000000000000$ echo "error: file not found" #=> --file notfound aureliojargas-clitest-8bdaae2/test/inline-match-file-error-3.sh000066400000000000000000000000541444513361400246520ustar00rootroot00000000000000$ echo "error: directory" #=> --file /etc/ aureliojargas-clitest-8bdaae2/test/inline-match-file.sh000066400000000000000000000023441444513361400233670ustar00rootroot00000000000000# Inline matching method: --file # Matches the contents of the informed file # Just inform the file path (no quotes, no escapes) $ printf '$ echo ok\nok\n' #=> --file ok-1.sh # Absolute paths are also supported $ echo 'ok' > /tmp/foo.txt $ echo 'ok' #=> --file /tmp/foo.txt $ rm /tmp/foo.txt $ # Syntax: Must be exactly one space before and after --file $ echo 'fail' #=> --file fail-with-2-spaces.txt $ echo 'fail' #=> --file fail-with-tab.txt # Syntax: The extra space after '--file ' is already part of the filename #$ echo 'fail' #=> --file file-with-leading-space-in-name.txt # Syntax: The space after --file is required. # When missing, the '--file' is considered a normal text. $ echo '--file' #=> --file # Syntax: Make sure we won't catch partial matches. $ echo '--filer' #=> --filer # Syntax: To insert a literal text that begins with '--file ' # just prefix it with --text. $ echo '--file is cool' #=> --text --file is cool # Syntax: Empty inline output contents are considered an error # Note: Tested in a separate file: inline-match-file-error-1.sh # # $ echo 'no contents' #=> --file aureliojargas-clitest-8bdaae2/test/inline-match-lines-error-1.sh000066400000000000000000000000521444513361400250410ustar00rootroot00000000000000$ echo 'error: no contents' #=> --lines aureliojargas-clitest-8bdaae2/test/inline-match-lines-error-2.sh000066400000000000000000000000601444513361400250410ustar00rootroot00000000000000$ echo 'error: negative number' #=> --lines -1 aureliojargas-clitest-8bdaae2/test/inline-match-lines-error-3.sh000066400000000000000000000000561444513361400250470ustar00rootroot00000000000000$ echo 'error: float number' #=> --lines 1.0 aureliojargas-clitest-8bdaae2/test/inline-match-lines-error-4.sh000066400000000000000000000000561444513361400250500ustar00rootroot00000000000000$ echo 'error: not a number' #=> --lines foo aureliojargas-clitest-8bdaae2/test/inline-match-lines.sh000066400000000000000000000030011444513361400235510ustar00rootroot00000000000000# Inline matching method: --lines # Count the number of lines in the output $ a=1 #=> --lines 0 $ echo 'ok' #=> --lines 1 $ printf '1\n2\n3\n' #=> --lines 3 # Lines without the final \n count as one full line $ printf 'no-nl' #=> --lines 1 $ printf '1\n2\nno-nl' #=> --lines 3 # The error message is a short sentence, not a diff # Example: Expected 99 lines, got 1. $ echo 'fail' #=> --lines 99 $ echo 'fail' #=> --lines 0 # Syntax: Must be exactly one space before and after --lines $ echo 'fail' #=> --lines fail with 2 spaces $ echo 'fail' #=> --lines fail with tab # Syntax: The space after --lines is required. # When missing, the '--lines' is considered a normal text. $ echo '--lines' #=> --lines # Syntax: Make sure we won't catch partial matches. $ echo '--linesout' #=> --linesout # Syntax: To insert a literal text that begins with '--lines ' # just prefix it with --text. $ echo '--lines is cool' #=> --text --lines is cool # Note: The following are tested in separate files: # inline-match-lines-error-?.sh # # Syntax: Empty inline output contents are considered an error # # $ echo 'no contents' #=> --lines # # Syntax: Must be an integer number # # $ echo 'fail' #=> --lines -1 # $ echo 'fail' #=> --lines 1.0 # $ echo 'fail' #=> --lines foo aureliojargas-clitest-8bdaae2/test/inline-match-perl-error-1.sh000066400000000000000000000000511444513361400246700ustar00rootroot00000000000000$ echo 'error: no contents' #=> --perl aureliojargas-clitest-8bdaae2/test/inline-match-perl-error-2.sh000066400000000000000000000007401444513361400246760ustar00rootroot00000000000000$ echo "error: malformed regex" #=> --perl ( # Some perl errors: # $ echo | perl -0777 -ne 'exit(!/(/)' ; echo $? # Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE / at -e line 1. # 255 # $ echo | perl -0777 -ne 'exit(!/[/)' ; echo $? # Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE / at -e line 1. # 255 # $ echo | perl -0777 -ne 'exit(!/**/)' ; echo $? # Quantifier follows nothing in regex; marked by <-- HERE in m/* <-- HERE */ at -e line 1. # 255 # $ aureliojargas-clitest-8bdaae2/test/inline-match-perl.sh000066400000000000000000000066651444513361400234240ustar00rootroot00000000000000# Inline matching method: --perl # Matches a Perl-style regular expression in the command output # You can also use the friendlier alias: --regex # # In fact, it's a real Perl match: perl -0777 -ne "exit(!m'regex')" # If Perl matched, we have a successful test. # All the test output lines are matched as a single string. # No modifiers are used by default, inform yours if needed: (?ims) # You don't need to escape the ' delimiter, the script will do it for you. # Just write your regex not worrying about delimiters. # Use anchors ^ and $ to match the full output text $ echo 'abc123' #=> --perl ^abc123$ $ echo 'abc123' #=> --perl ^abc.*3$ $ echo 'abc123' #=> --perl ^abc[0-9]+$ # Omit one or both anchors to make a parcial match $ echo 'abc123' #=> --perl ^abc $ echo 'abc123' #=> --perl 123$ $ echo 'abc123' #=> --perl [0-9]+$ $ echo 'abc123' #=> --perl bc $ echo 'abc123' #=> --perl . # Blanks are preserved, no escaping or quoting needed $ echo 'abc 123' #=> --perl ^abc [0-9]+$ # Blank output can also be matched $ echo ' ' #=> --perl ^ $ $ echo ' ' #=> --perl ^ $ $ printf '\t\n' #=> --perl ^ $ $ printf '\t\t\t\n' #=> --perl ^ $ $ printf ' \t \t\t \n' #=> --perl ^ $ # You don't need to escape any delimiters, escapes are handled by the script $ echo '01/01/2013' #=> --perl ^../../....$ $ echo "won't fail" #=> --perl ^won't \w+$ # To match a tab, you can use \t or a literal tab $ printf 'will\tmatch' #=> --perl ^will\tmatch$ $ printf 'will\tmatch' #=> --perl ^will[\t]match$ $ printf 'will\tmatch' #=> --perl ^will match$ # You need to inform the (?i) modifier to match ignoring case $ printf 'will\nfail' #=> --perl ^WILL $ printf 'will\nmatch' #=> --perl (?i)^WILL # You need to inform the (?s) modifier for the dot to match \n $ printf 'will\nfail' #=> --perl ^will.fail$ $ printf 'will\nmatch' #=> --perl (?s)^will.match$ # You need to inform the (?m) modifier for ^ and $ to match inner lines $ printf 'will\nfail' #=> --perl ^fail $ printf 'will\nmatch' #=> --perl (?m)^match # Perl ignores the last \n, in both the text and the regex $ printf 'ok' #=> --perl ^ok$ $ printf 'ok\n' #=> --perl ^ok$ $ printf '1\n2\n3\n' #=> --perl ^1\n2\n3\n$ $ printf '1\n2\n3\n' #=> --perl ^1\n2\n3$ # Syntax: Must be exactly one space before and after --perl $ echo 'fail' #=> --perl fail with 2 spaces $ echo 'fail' #=> --perl fail with tab # Syntax: The extra space after '--perl ' is already part of the regex $ echo ' ok' #=> --perl ok # Syntax: The space after --perl is required. # When missing, the '--perl' is considered a normal text. $ echo '--perl' #=> --perl # Syntax: Make sure we won't catch partial matches. $ echo '--perlism' #=> --perlism # Syntax: To insert a literal text that begins with '--perl ' # just prefix it with --text. $ echo '--perl is cool' #=> --text --perl is cool # Syntax: Empty inline output contents are considered an error # Note: Tested in a separate file: inline-match-perl-error-1.sh # # $ echo 'no contents' #=> --perl aureliojargas-clitest-8bdaae2/test/inline-match-text.sh000066400000000000000000000055041444513361400234350ustar00rootroot00000000000000# Inline matching method: --text # Matches a literal text # This is the default method, the --text part can be omitted. $ echo 'abc' #=> --text abc $ echo 'abc' #=> abc # Special characters as \t and \n are not expanded. $ printf '%s\n' '\t' #=> \t $ printf '%s\n' '\n' #=> \n # Variables and commands are not parsed (see #=> --eval for that). $ echo '$PWD' #=> $PWD $ echo '$(date)' #=> $(date) # It's a literal text, with no special characters. $ echo '$' #=> $ $ echo '>' #=> > $ echo '?' #=> ? $ echo '!' #=> ! $ echo '*' #=> * $ echo '[' #=> [ $ echo '(' #=> ( # For commands that return an empty line, just leave it empty $ echo #=> # But don't forget the blank space after the →, because in this # case the #=> marker will be considered a plain comment and ignored $ echo "not inline output" #=> not inline output $ # Blanks are preserved $ echo '123456789' #=> 123456789 $ echo '1 3 7 9' #=> 1 3 7 9 $ echo ' 5 ' #=> 5 $ echo ' leading space' #=> leading space $ echo ' leading spaces' #=> leading spaces $ printf '\tleading tab\n' #=> leading tab $ printf '\t\tleading tabs\n' #=> leading tabs $ echo 'trailing space ' #=> trailing space $ echo 'trailing spaces ' #=> trailing spaces $ printf 'trailing tab\t\n' #=> trailing tab $ printf 'trailing tabs\t\t\n' #=> trailing tabs $ echo ' ' #=> $ echo ' ' #=> $ printf '\t\n' #=> $ printf '\t\t\t\n' #=> $ printf ' \t \t\t \n' #=> # As seen in all these examples, the final \n is implied. # You can't match lines with no \n. $ printf 'ok\n' #=> ok $ printf 'fail' #=> fail # An easy workaround is to add an empty 'echo' at the end: $ printf 'ok'; echo #=> ok # Syntax: Must be exactly one space before and after --text $ echo 'fail' #=> --text fail with 2 spaces $ echo 'fail' #=> --text fail with tab # Syntax: The extra space after '--text ' is already part of the output $ echo ' ok' #=> --text ok # Syntax: The space after --text is required. # When missing, the '--text' is considered a normal text. $ echo '--text' #=> --text # Syntax: Make sure we won't catch partial matches. $ echo '--textual' #=> --textual # Syntax: To insert a literal text that begins with '--text ' # just prefix it with another --text. $ echo '--text is cool' #=> --text --text is cool aureliojargas-clitest-8bdaae2/test/inline-multiple-marker.sh000066400000000000000000000002611444513361400244640ustar00rootroot00000000000000# If multiple markers, only the last one is identified as such # There are 4 ' #=> ' marker-like occurrences in this test. $ echo "a #=> b #=> c" #=> --lines 99 #=> --lines 1 aureliojargas-clitest-8bdaae2/test/inline.sh000066400000000000000000000020601444513361400213530ustar00rootroot00000000000000# The blank space before the #=> marker matters? $ echo 'one space' #=> one space $ echo 'one tab' #=> one tab $ echo 'multi spaces' #=> multi spaces $ echo 'multi tabs' #=> multi tabs $ echo 'mixed' #=> mixed # Blank lines and comments in the middle. # No need to 'close' previous command. # Leading and trailing blank space are preserved? $ echo ' leading space' #=> leading space $ echo ' leading spaces' #=> leading spaces $ printf '\tleading tab\n' #=> leading tab $ printf '\t\tleading tabs\n' #=> leading tabs $ echo 'trailing space ' #=> trailing space $ echo 'trailing spaces ' #=> trailing spaces $ printf 'trailing tab\t\n' #=> trailing tab $ printf 'trailing tabs\t\t\n' #=> trailing tabs # Blank output $ echo ' ' #=> $ echo ' ' #=> $ printf '\t\n' #=> $ printf '\t\t\t\n' #=> $ printf ' \t \t\t \n' #=> # Inline results have precedence over normal results $ echo "both inline and normal output" #=> both inline and normal output Inline wins. The normal output is just ignored. $ aureliojargas-clitest-8bdaae2/test/lorem-ipsum.txt000066400000000000000000000003051444513361400225530ustar00rootroot00000000000000Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod blandit pharetra. Vestibulum eu neque eget lorem gravida commodo a cursus massa. Fusce sit amet lorem sem. Donec eu quam leo. aureliojargas-clitest-8bdaae2/test/multi-commands.sh000066400000000000000000000002521444513361400230270ustar00rootroot00000000000000$ echo 1; echo 2; echo 3; echo 4; echo 5 1 2 3 4 5 $ (echo 1; echo 2; echo 3; echo 4; echo 5) | sed -n 3p 3 $ (echo 1; echo 2; echo 3; echo 4; echo 5) | sed -n 3p #=> 3 aureliojargas-clitest-8bdaae2/test/no-nl-command.sh000066400000000000000000000007201444513361400225350ustar00rootroot00000000000000# All results assume a trailing newline (\n) at the last line. # Outputs with no \n at the end cannot be tested directly. $ printf 'ok\n' ok $ printf 'fail' fail $ printf 'ok\nok\nfail' ok ok fail $ # The same applies for inline output. $ printf 'ok\n' #=> ok $ printf 'fail' #=> fail # An easy workaround is to add an empty 'echo' at the end: $ printf 'ok'; echo #=> ok # Another workaround is to use --regex $ printf 'ok' #=> --regex ^ok$ aureliojargas-clitest-8bdaae2/test/no-nl-file-1.sh000066400000000000000000000001271444513361400221750ustar00rootroot00000000000000$ printf '%s\n' 'a file with no \n at the last line' a file with no \n at the last lineaureliojargas-clitest-8bdaae2/test/no-nl-file-2.sh000066400000000000000000000001451444513361400221760ustar00rootroot00000000000000$ printf '%s\n' 'another file with no \n at the last line' another file with no \n at the last line $aureliojargas-clitest-8bdaae2/test/no-nl-file-3.sh000066400000000000000000000000661444513361400222010ustar00rootroot00000000000000$ printf '%s\n' 'oneliner, no \n' #=> oneliner, no \naureliojargas-clitest-8bdaae2/test/no-test-found.sh000066400000000000000000000003461444513361400226040ustar00rootroot00000000000000# A file with comments, but no test :( # It raises an error when processed, because the user must # take action in this situation: # # 1) fix the file, adding the tests # or # 2) stop sending this file to the tester aureliojargas-clitest-8bdaae2/test/ok-1.sh000066400000000000000000000000151444513361400206420ustar00rootroot00000000000000$ echo ok ok aureliojargas-clitest-8bdaae2/test/ok-10.sh000066400000000000000000000002301444513361400207210ustar00rootroot00000000000000$ echo 1 #=> 1 $ echo 2 #=> 2 $ echo 3 #=> 3 $ echo 4 #=> 4 $ echo 5 #=> 5 $ echo 6 #=> 6 $ echo 7 #=> 7 $ echo 8 #=> 8 $ echo 9 #=> 9 $ echo 10 #=> 10 aureliojargas-clitest-8bdaae2/test/ok-100.sh000066400000000000000000000032241444513361400210070ustar00rootroot00000000000000$ echo 1 #=> 1 $ echo 2 #=> 2 $ echo 3 #=> 3 $ echo 4 #=> 4 $ echo 5 #=> 5 $ echo 6 #=> 6 $ echo 7 #=> 7 $ echo 8 #=> 8 $ echo 9 #=> 9 $ echo 10 #=> 10 $ echo 11 #=> 11 $ echo 12 #=> 12 $ echo 13 #=> 13 $ echo 14 #=> 14 $ echo 15 #=> 15 $ echo 16 #=> 16 $ echo 17 #=> 17 $ echo 18 #=> 18 $ echo 19 #=> 19 $ echo 20 #=> 20 $ echo 21 #=> 21 $ echo 22 #=> 22 $ echo 23 #=> 23 $ echo 24 #=> 24 $ echo 25 #=> 25 $ echo 26 #=> 26 $ echo 27 #=> 27 $ echo 28 #=> 28 $ echo 29 #=> 29 $ echo 30 #=> 30 $ echo 31 #=> 31 $ echo 32 #=> 32 $ echo 33 #=> 33 $ echo 34 #=> 34 $ echo 35 #=> 35 $ echo 36 #=> 36 $ echo 37 #=> 37 $ echo 38 #=> 38 $ echo 39 #=> 39 $ echo 40 #=> 40 $ echo 41 #=> 41 $ echo 42 #=> 42 $ echo 43 #=> 43 $ echo 44 #=> 44 $ echo 45 #=> 45 $ echo 46 #=> 46 $ echo 47 #=> 47 $ echo 48 #=> 48 $ echo 49 #=> 49 $ echo 50 #=> 50 $ echo 51 #=> 51 $ echo 52 #=> 52 $ echo 53 #=> 53 $ echo 54 #=> 54 $ echo 55 #=> 55 $ echo 56 #=> 56 $ echo 57 #=> 57 $ echo 58 #=> 58 $ echo 59 #=> 59 $ echo 60 #=> 60 $ echo 61 #=> 61 $ echo 62 #=> 62 $ echo 63 #=> 63 $ echo 64 #=> 64 $ echo 65 #=> 65 $ echo 66 #=> 66 $ echo 67 #=> 67 $ echo 68 #=> 68 $ echo 69 #=> 69 $ echo 70 #=> 70 $ echo 71 #=> 71 $ echo 72 #=> 72 $ echo 73 #=> 73 $ echo 74 #=> 74 $ echo 75 #=> 75 $ echo 76 #=> 76 $ echo 77 #=> 77 $ echo 78 #=> 78 $ echo 79 #=> 79 $ echo 80 #=> 80 $ echo 81 #=> 81 $ echo 82 #=> 82 $ echo 83 #=> 83 $ echo 84 #=> 84 $ echo 85 #=> 85 $ echo 86 #=> 86 $ echo 87 #=> 87 $ echo 88 #=> 88 $ echo 89 #=> 89 $ echo 90 #=> 90 $ echo 91 #=> 91 $ echo 92 #=> 92 $ echo 93 #=> 93 $ echo 94 #=> 94 $ echo 95 #=> 95 $ echo 96 #=> 96 $ echo 97 #=> 97 $ echo 98 #=> 98 $ echo 99 #=> 99 $ echo 100 #=> 100 aureliojargas-clitest-8bdaae2/test/ok-2.sh000066400000000000000000000000371444513361400206470ustar00rootroot00000000000000$ echo ok ok $ echo ok #=> ok aureliojargas-clitest-8bdaae2/test/ok-50.sh000066400000000000000000000015001444513361400207260ustar00rootroot00000000000000$ echo 1 #=> 1 $ echo 2 #=> 2 $ echo 3 #=> 3 $ echo 4 #=> 4 $ echo 5 #=> 5 $ echo 6 #=> 6 $ echo 7 #=> 7 $ echo 8 #=> 8 $ echo 9 #=> 9 $ echo 10 #=> 10 $ echo 11 #=> 11 $ echo 12 #=> 12 $ echo 13 #=> 13 $ echo 14 #=> 14 $ echo 15 #=> 15 $ echo 16 #=> 16 $ echo 17 #=> 17 $ echo 18 #=> 18 $ echo 19 #=> 19 $ echo 20 #=> 20 $ echo 21 #=> 21 $ echo 22 #=> 22 $ echo 23 #=> 23 $ echo 24 #=> 24 $ echo 25 #=> 25 $ echo 26 #=> 26 $ echo 27 #=> 27 $ echo 28 #=> 28 $ echo 29 #=> 29 $ echo 30 #=> 30 $ echo 31 #=> 31 $ echo 32 #=> 32 $ echo 33 #=> 33 $ echo 34 #=> 34 $ echo 35 #=> 35 $ echo 36 #=> 36 $ echo 37 #=> 37 $ echo 38 #=> 38 $ echo 39 #=> 39 $ echo 40 #=> 40 $ echo 41 #=> 41 $ echo 42 #=> 42 $ echo 43 #=> 43 $ echo 44 #=> 44 $ echo 45 #=> 45 $ echo 46 #=> 46 $ echo 47 #=> 47 $ echo 48 #=> 48 $ echo 49 #=> 49 $ echo 50 #=> 50 aureliojargas-clitest-8bdaae2/test/option-debug-color.sh000066400000000000000000000000311444513361400236010ustar00rootroot00000000000000$ echo "tab " #=> tab $ aureliojargas-clitest-8bdaae2/test/option-debug.sh000066400000000000000000000002331444513361400224710ustar00rootroot00000000000000# Test file to be run with --debug $ echo "tab+space " #=> tab+space $ # A comment line between command blocks $ echo "unclosed block" unclosed block aureliojargas-clitest-8bdaae2/test/option-diff-options.sh000066400000000000000000000002711444513361400240060ustar00rootroot00000000000000# Configurable diff options with --diff-options $ echo " diff -w to ignore spaces " diff -w to ignore spaces $ echo " diff -w now inline " #=> diff -w now inline aureliojargas-clitest-8bdaae2/test/option-inline-prefix.sh000066400000000000000000000002161444513361400241550ustar00rootroot00000000000000# Configurable prefix with --inline-prefix $ echo "1 space" #==> 1 space $ echo "8 spaces" #==> 8 spaces $ echo "2 tabs" #==> 2 tabs aureliojargas-clitest-8bdaae2/test/option-prefix-glob.sh000066400000000000000000000014471444513361400236310ustar00rootroot00000000000000/// Gotcha: glob chars as --prefix: ? * # ## #* *# #*# % %% %* *% %*% /// Inline output ?$ echo 'prefix ?' #=> prefix ? *$ echo 'prefix *' #=> prefix * #$ echo 'prefix #' #=> prefix # %$ echo 'prefix %' #=> prefix % ##$ echo 'prefix ##' #=> prefix ## %%$ echo 'prefix %%' #=> prefix %% #*$ echo 'prefix #*' #=> prefix #* *#$ echo 'prefix *#' #=> prefix *# %*$ echo 'prefix %*' #=> prefix %* *%$ echo 'prefix *%' #=> prefix *% /// Normal output ?$ echo 'prefix ?' ?prefix ? ?$ *$ echo 'prefix *' *prefix * *$ #$ echo 'prefix #' #prefix # #$ %$ echo 'prefix %' %prefix % %$ ##$ echo 'prefix ##' ##prefix ## ##$ %%$ echo 'prefix %%' %%prefix %% %%$ #*$ echo 'prefix #*' #*prefix #* #*$ *#$ echo 'prefix *#' *#prefix *# *#$ %*$ echo 'prefix %*' %*prefix %* %*$ *%$ echo 'prefix *%' *%prefix *% *%$ aureliojargas-clitest-8bdaae2/test/option-prefix-tab.sh000066400000000000000000000016361444513361400234540ustar00rootroot00000000000000# Test file for the --prefix option # Command blocks here are prefixed by a tab # Run with --prefix '\t' or --prefix tab $ echo "1" #=> 1 $ echo "2" 2 # Any non-prefixed line closes the previous command block. # The empty $ line is not needed. # All other non-indented text is just ignored: $ echo "ignored" # not indented $ echo "ignored" #=> not indented # Lines with the wrong indentation are also ignored $ echo "ignored" # 2 tabs $ echo "ignored" # 8 spaces $ echo "ignored" # 4 spaces # Multiple blocks supported in a single file $ echo "3" 3 # What about prefixed blocks with no commands? Prefixed line with no prompt: ignored. But wait, here comes a command: $ echo "4" 4 $ Last command closed by the empty prompt. $ echo "5" #=> 5 Last command is auto-closed (inline output). # Blank lines in the output are supported $ echo; echo "6"; echo; echo "7" 6 7 # Nice. aureliojargas-clitest-8bdaae2/test/option-prefix.sh000066400000000000000000000017071444513361400227070ustar00rootroot00000000000000# Test file for the --prefix option # Command blocks here are prefixed by 4 spaces (Markdown-style) # Run with --prefix ' ' or --prefix 4 $ echo "1" #=> 1 $ echo "2" 2 # Any non-prefixed line closes the previous command block. # The empty $ line is not needed. # All other non-indented text is just ignored: $ echo "ignored" # not indented $ echo "ignored" #=> not indented # Lines with the wrong indentation are also ignored $ echo "ignored" # 3 spaces $ echo "ignored" # 5 spaces # Multiple blocks supported in a single file $ echo "3" 3 # What about prefixed blocks with no commands? Prefixed line with no prompt: ignored. But wait, here comes a command: $ echo "4" 4 $ Last command closed by the empty prompt. $ echo "5" #=> 5 Last command is auto-closed (inline output). # Blank lines in the output are supported $ echo; echo "6"; echo; echo "7" 6 7 # Nice. aureliojargas-clitest-8bdaae2/test/option-prompt-glob-1.sh000066400000000000000000000007121444513361400240050ustar00rootroot00000000000000/// Gotcha: glob chars as --prompt: ? * # % /// Note: These tests are separated from the two chars globs /// to avoid partial matches with wrong output. /// Inline output (one char) ?echo 'prompt ?' #=> prompt ? *echo 'prompt *' #=> prompt * #echo 'prompt #' #=> prompt # %echo 'prompt %' #=> prompt % /// Normal output (one char) ?echo 'prompt ?' prompt ? ? *echo 'prompt *' prompt * * #echo 'prompt #' prompt # # %echo 'prompt %' prompt % % aureliojargas-clitest-8bdaae2/test/option-prompt-glob-2.sh000066400000000000000000000013361444513361400240110ustar00rootroot00000000000000/// Gotcha: glob chars as --prompt: ? * # % ## %% #* *# %* *% /// Inline output ?echo 'prompt ?' #=> prompt ? *echo 'prompt *' #=> prompt * #echo 'prompt #' #=> prompt # %echo 'prompt %' #=> prompt % ##echo 'prompt ##' #=> prompt ## %%echo 'prompt %%' #=> prompt %% #*echo 'prompt #*' #=> prompt #* *#echo 'prompt *#' #=> prompt *# %*echo 'prompt %*' #=> prompt %* *%echo 'prompt *%' #=> prompt *% /// Normal output ?echo 'prompt ?' prompt ? ? *echo 'prompt *' prompt * * #echo 'prompt #' prompt # # %echo 'prompt %' prompt % % ##echo 'prompt ##' prompt ## ## %%echo 'prompt %%' prompt %% %% #*echo 'prompt #*' prompt #* #* *#echo 'prompt *#' prompt *# *# %*echo 'prompt %*' prompt %* %* *%echo 'prompt *%' prompt *% *% aureliojargas-clitest-8bdaae2/test/option-prompt-glob-space.sh000066400000000000000000000014471444513361400247460ustar00rootroot00000000000000/// Gotcha: glob chars (plus space) as --prompt: ? * # ## #* *# % %% %* *% /// Inline output ? echo 'prompt ? ' #=> prompt ? * echo 'prompt * ' #=> prompt * # echo 'prompt # ' #=> prompt # % echo 'prompt % ' #=> prompt % ## echo 'prompt ## ' #=> prompt ## %% echo 'prompt %% ' #=> prompt %% #* echo 'prompt #* ' #=> prompt #* *# echo 'prompt *# ' #=> prompt *# %* echo 'prompt %* ' #=> prompt %* *% echo 'prompt *% ' #=> prompt *% /// Normal output ? echo 'prompt ? ' prompt ? ? * echo 'prompt * ' prompt * * # echo 'prompt # ' prompt # # % echo 'prompt % ' prompt % % ## echo 'prompt ## ' prompt ## ## %% echo 'prompt %% ' prompt %% %% #* echo 'prompt #* ' prompt #* #* *# echo 'prompt *# ' prompt *# *# %* echo 'prompt %* ' prompt %* %* *% echo 'prompt *% ' prompt *% *% aureliojargas-clitest-8bdaae2/test/option-prompt-unicode.sh000066400000000000000000000003001444513361400243430ustar00rootroot00000000000000# Configurable prompt with --prompt ♥ echo "1" #=> 1 ♥ echo "2" 2 ♥ # Series closed with empty prompt ♥ echo "3" 3 ♥ # Series closed with empty prompt (with no trailing space) aureliojargas-clitest-8bdaae2/test/option-prompt.sh000066400000000000000000000003241444513361400227250ustar00rootroot00000000000000# Configurable prompt with --prompt prompt$ echo "1" #=> 1 prompt$ echo "2" 2 prompt$ # Series closed with empty prompt prompt$ echo "3" 3 prompt$ # Series closed with empty prompt (with no trailing space) aureliojargas-clitest-8bdaae2/test/special-chars.sh000066400000000000000000000103261444513361400226170ustar00rootroot00000000000000# ASCII $ echo '0123456789' #=> 0123456789 $ echo 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' #=> ABCDEFGHIJKLMNOPQRSTUVWXYZ $ echo 'abcdefghijklmnopqrstuvwxyz' #=> abcdefghijklmnopqrstuvwxyz $ echo ' ' #=> $ echo '!' #=> ! $ echo '"' #=> " $ echo '#' #=> # $ echo '$' #=> $ $ echo '%' #=> % $ echo '&' #=> & $ echo "'" #=> ' $ echo '(' #=> ( $ echo ')' #=> ) $ echo '*' #=> * $ echo '+' #=> + $ echo ',' #=> , $ echo '-' #=> - $ echo '.' #=> . $ echo '/' #=> / $ echo ':' #=> : $ echo ';' #=> ; $ echo '<' #=> < $ echo '=' #=> = $ echo '>' #=> > $ echo '?' #=> ? $ echo '@' #=> @ $ echo '[' #=> [ $ echo '\' #=> \ $ echo ']' #=> ] $ echo '^' #=> ^ $ echo '_' #=> _ $ echo '`' #=> ` $ echo '{' #=> { $ echo '|' #=> | $ echo '}' #=> } $ echo '~' #=> ~ # !ASCII $ echo '¡' #=> ¡ $ echo '¢' #=> ¢ $ echo '£' #=> £ $ echo '¤' #=> ¤ $ echo '¥' #=> ¥ $ echo '¦' #=> ¦ $ echo '§' #=> § $ echo '¨' #=> ¨ $ echo '©' #=> © $ echo 'ª' #=> ª $ echo '«' #=> « $ echo '¬' #=> ¬ $ echo '­' #=> ­ $ echo '®' #=> ® $ echo '°' #=> ° $ echo '±' #=> ± $ echo '²' #=> ² $ echo '³' #=> ³ $ echo '´' #=> ´ $ echo 'µ' #=> µ $ echo '¶' #=> ¶ $ echo '·' #=> · $ echo '¹' #=> ¹ $ echo 'º' #=> º $ echo '»' #=> » $ echo '¼' #=> ¼ $ echo '½' #=> ½ $ echo '¾' #=> ¾ $ echo '¿' #=> ¿ $ echo 'À' #=> À $ echo 'Á' #=> Á $ echo 'Â' #=>  $ echo 'Ã' #=> à $ echo 'Ä' #=> Ä $ echo 'Å' #=> Å $ echo 'Æ' #=> Æ $ echo 'Ç' #=> Ç $ echo 'È' #=> È $ echo 'É' #=> É $ echo 'Ê' #=> Ê $ echo 'Ë' #=> Ë $ echo 'Ì' #=> Ì $ echo 'Í' #=> Í $ echo 'Î' #=> Î $ echo 'Ï' #=> Ï $ echo 'Ð' #=> Ð $ echo 'Ñ' #=> Ñ $ echo 'Ò' #=> Ò $ echo 'Ó' #=> Ó $ echo 'Ô' #=> Ô $ echo 'Õ' #=> Õ $ echo 'Ö' #=> Ö $ echo '×' #=> × $ echo 'Ø' #=> Ø $ echo 'Ù' #=> Ù $ echo 'Ú' #=> Ú $ echo 'Û' #=> Û $ echo 'Ü' #=> Ü $ echo 'Ý' #=> Ý $ echo 'ß' #=> ß $ echo 'à' #=> à $ echo 'á' #=> á $ echo 'â' #=> â $ echo 'ã' #=> ã $ echo 'ä' #=> ä $ echo 'å' #=> å $ echo 'æ' #=> æ $ echo 'ç' #=> ç $ echo 'è' #=> è $ echo 'é' #=> é $ echo 'ê' #=> ê $ echo 'ë' #=> ë $ echo 'ì' #=> ì $ echo 'í' #=> í $ echo 'î' #=> î $ echo 'ï' #=> ï $ echo 'ð' #=> ð $ echo 'ñ' #=> ñ $ echo 'ò' #=> ò $ echo 'ó' #=> ó $ echo 'ô' #=> ô $ echo 'õ' #=> õ $ echo 'ö' #=> ö $ echo '÷' #=> ÷ $ echo 'ø' #=> ø $ echo 'ù' #=> ù $ echo 'ú' #=> ú $ echo 'û' #=> û $ echo 'ü' #=> ü $ echo 'ý' #=> ý $ echo 'ÿ' #=> ÿ $ echo 'Œ' #=> Œ $ echo 'œ' #=> œ $ echo 'Ÿ' #=> Ÿ $ echo 'ƒ' #=> ƒ $ echo 'Α' #=> Α $ echo 'Β' #=> Β $ echo 'Π' #=> Π $ echo 'Σ' #=> Σ $ echo 'Φ' #=> Φ $ echo 'Ω' #=> Ω $ echo 'α' #=> α $ echo 'β' #=> β $ echo 'η' #=> η $ echo 'μ' #=> μ $ echo 'π' #=> π $ echo 'ω' #=> ω $ echo 'ϖ' #=> ϖ $ echo '–' #=> – $ echo '—' #=> — $ echo '‘' #=> ‘ $ echo '’' #=> ’ $ echo '‚' #=> ‚ $ echo '“' #=> “ $ echo '”' #=> ” $ echo '„' #=> „ $ echo '†' #=> † $ echo '‡' #=> ‡ $ echo '•' #=> • $ echo '…' #=> … $ echo '‰' #=> ‰ $ echo '′' #=> ′ $ echo '″' #=> ″ $ echo '‹' #=> ‹ $ echo '›' #=> › $ echo '‾' #=> ‾ $ echo '⁄' #=> ⁄ $ echo '€' #=> € $ echo '™' #=> ™ $ echo '←' #=> ← $ echo '↑' #=> ↑ $ echo '→' #=> → $ echo '↓' #=> ↓ $ echo '↔' #=> ↔ $ echo '↵' #=> ↵ $ echo '⇐' #=> ⇐ $ echo '⇑' #=> ⇑ $ echo '⇒' #=> ⇒ $ echo '⇓' #=> ⇓ $ echo '⇔' #=> ⇔ $ echo '∈' #=> ∈ $ echo '∉' #=> ∉ $ echo '∋' #=> ∋ $ echo '∏' #=> ∏ $ echo '∑' #=> ∑ $ echo '−' #=> − $ echo '∗' #=> ∗ $ echo '√' #=> √ $ echo '∝' #=> ∝ $ echo '∞' #=> ∞ $ echo '∫' #=> ∫ $ echo '∴' #=> ∴ $ echo '∼' #=> ∼ $ echo '≅' #=> ≅ $ echo '≈' #=> ≈ $ echo '≠' #=> ≠ $ echo '≡' #=> ≡ $ echo '≤' #=> ≤ $ echo '≥' #=> ≥ $ echo '⊂' #=> ⊂ $ echo '⊃' #=> ⊃ $ echo '⊄' #=> ⊄ $ echo '⊆' #=> ⊆ $ echo '⊇' #=> ⊇ $ echo '◊' #=> ◊ $ echo '♠' #=> ♠ $ echo '♣' #=> ♣ $ echo '♥' #=> ♥ $ echo '♦' #=> ♦ $ echo '★' #=> ★ aureliojargas-clitest-8bdaae2/test/stdin-isolation.sh000066400000000000000000000007041444513361400232200ustar00rootroot00000000000000# # This was a bug found on early versions of clitest in which tests shared # STDIN with clitest and with each other, causing unexpected results when # a test read from STDIN. This was reported on issue #42 on Github. # # Testing for a regression. # $ echo testing stdin isolation ; read stdin_isolation testing stdin isolation $ echo Failed\? Regression to stdin isolation added. ; unset stdin_isolation Failed? Regression to stdin isolation added. aureliojargas-clitest-8bdaae2/test/stdout-stderr.sh000066400000000000000000000012611444513361400227220ustar00rootroot00000000000000# Output from both STDOUT and STDERR are catched by the tester. ### STDOUT # Showing STOUT $ echo "stdout" stdout $ echo "stdout" 2> /dev/null stdout $ # Redirecting STDOUT to STDERR $ echo "stderr" 1>&2 stderr $ # Closing STDOUT $ echo "stdout" > /dev/null $ echo "stdout" 2> /dev/null 1>&2 $ ### STDERR # Showing STDERR $ ./clitest notfound clitest: Error: cannot read input file: notfound $ ./clitest notfound > /dev/null clitest: Error: cannot read input file: notfound $ # Redirecting STDERR to STDOUT $ ./clitest notfound 2>&1 clitest: Error: cannot read input file: notfound $ # Closing STDERR $ ./clitest notfound 2> /dev/null $ ./clitest notfound > /dev/null 2>&1 $ aureliojargas-clitest-8bdaae2/test/windows.sh000066400000000000000000000002461444513361400215730ustar00rootroot00000000000000$ echo "a file with CRLF line ending" a file with CRLF line ending $ $ echo "inline output" #=> inline output $ echo "inline regex" #=> --regex ^inline regex$