diff --git a/stdlib/bats/tests/testfile/mods/bats-assert/CHANGELOG.md b/stdlib/bats/tests/testfile/mods/bats-assert/CHANGELOG.md new file mode 100644 index 00000000..7e326f47 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-assert/CHANGELOG.md @@ -0,0 +1,39 @@ +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + + +## [0.3.0] - 2016-03-22 + +### Removed + +- Move `fail()` to `bats-support` + + +## [0.2.0] - 2016-03-11 + +### Added + +- `refute()` to complement `assert()` +- `npm` support + +### Fixed + +- Not consuming the `--` when stopping option parsing in + `assert_output`, `refute_output`, `assert_line` and `refute_line` + + +## 0.1.0 - 2016-02-16 + +### Added + +- Reporting arbitrary failures with `fail()` +- Generic assertions with `assert()` and `assert_equal()` +- Testing exit status with `assert_success()` and `assert_failure()` +- Testing output with `assert_output()` and `refute_output()` +- Testing individual lines with `assert_line()` and `refute_line()` + + +[0.3.0]: https://github.com/ztombol/bats-assert/compare/v0.2.0...v0.3.0 +[0.2.0]: https://github.com/ztombol/bats-assert/compare/v0.1.0...v0.2.0 diff --git a/stdlib/bats/tests/testfile/mods/bats-assert/LICENSE b/stdlib/bats/tests/testfile/mods/bats-assert/LICENSE new file mode 100644 index 00000000..670154e3 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-assert/LICENSE @@ -0,0 +1,116 @@ +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + diff --git a/stdlib/bats/tests/testfile/mods/bats-assert/README.md b/stdlib/bats/tests/testfile/mods/bats-assert/README.md new file mode 100644 index 00000000..dfe78a42 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-assert/README.md @@ -0,0 +1,712 @@ +# bats-assert + +[![License](https://img.shields.io/npm/l/bats-assert.svg)](https://github.com/jasonkarns/bats-assert-1/blob/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/jasonkarns/bats-assert-1.svg)](https://github.com/jasonkarns/bats-assert-1/releases) +[![npm release](https://img.shields.io/npm/v/bats-assert.svg)](https://www.npmjs.com/package/bats-assert) +[![Build Status](https://travis-ci.org/jasonkarns/bats-assert-1.svg?branch=master)](https://travis-ci.org/jasonkarns/bats-assert-1) + +`bats-assert` is a helper library providing common assertions for +[Bats][bats]. + +Assertions are functions that perform a test and output relevant +information on failure to help debugging. They return 1 on failure and 0 +otherwise. Output, [formatted][bats-support-output] for readability, is +sent to the standard error to make assertions usable outside of `@test` +blocks too. + +Assertions testing exit code and output operate on the results of the +most recent invocation of `run`. + +Dependencies: +- [`bats-support`][bats-support] (formerly `bats-core`) - output + formatting + +See the [shared documentation][bats-docs] to learn how to install and +load this library. + + +## Usage + +### `assert` + +Fail if the given expression evaluates to false. + +***Note:*** *The expression must be a simple command. [Compound +commands][bash-comp-cmd], such as `[[`, can be used only when executed +with `bash -c`.* + +```bash +@test 'assert()' { + touch '/var/log/test.log' + assert [ -e '/var/log/test.log' ] +} +``` + +On failure, the failed expression is displayed. + +``` +-- assertion failed -- +expression : [ -e /var/log/test.log ] +-- +``` + + +### `refute` + +Fail if the given expression evaluates to true. + +***Note:*** *The expression must be a simple command. [Compound +commands][bash-comp-cmd], such as `[[`, can be used only when executed +with `bash -c`.* + +```bash +@test 'refute()' { + rm -f '/var/log/test.log' + refute [ -e '/var/log/test.log' ] +} +``` + +On failure, the successful expression is displayed. + +``` +-- assertion succeeded, but it was expected to fail -- +expression : [ -e /var/log/test.log ] +-- +``` + + +### `assert_equal` + +Fail if the two parameters, actual and expected value respectively, do +not equal. + +```bash +@test 'assert_equal()' { + assert_equal 'have' 'want' +} +``` + +On failure, the expected and actual values are displayed. + +``` +-- values do not equal -- +expected : want +actual : have +-- +``` + +If either value is longer than one line both are displayed in +*multi-line* format. + + +### `assert_success` + +Fail if `$status` is not 0. + +```bash +@test 'assert_success() status only' { + run bash -c "echo 'Error!'; exit 1" + assert_success +} +``` + +On failure, `$status` and `$output` are displayed. + +``` +-- command failed -- +status : 1 +output : Error! +-- +``` + +If `$output` is longer than one line, it is displayed in *multi-line* +format. + + +### `assert_failure` + +Fail if `$status` is 0. + +```bash +@test 'assert_failure() status only' { + run echo 'Success!' + assert_failure +} +``` + +On failure, `$output` is displayed. + +``` +-- command succeeded, but it was expected to fail -- +output : Success! +-- +``` + +If `$output` is longer than one line, it is displayed in *multi-line* +format. + +#### Expected status + +When one parameter is specified, fail if `$status` does not equal the +expected status specified by the parameter. + +```bash +@test 'assert_failure() with expected status' { + run bash -c "echo 'Error!'; exit 1" + assert_failure 2 +} +``` + +On failure, the expected and actual status, and `$output` are displayed. + +``` +-- command failed as expected, but status differs -- +expected : 2 +actual : 1 +output : Error! +-- +``` + +If `$output` is longer than one line, it is displayed in *multi-line* +format. + + +### `assert_output` + +This function helps to verify that a command or function produces the +correct output by checking that the specified expected output matches +the actual output. Matching can be literal (default), partial or regular +expression. This function is the logical complement of `refute_output`. + +#### Literal matching + +By default, literal matching is performed. The assertion fails if +`$output` does not equal the expected output. + +```bash +@test 'assert_output()' { + run echo 'have' + assert_output 'want' +} +``` + +On failure, the expected and actual output are displayed. + +``` +-- output differs -- +expected : want +actual : have +-- +``` + +If either value is longer than one line both are displayed in +*multi-line* format. + +#### Existence + +To assert that any (non-empty) output exists at all, simply omit the matching +argument. + +```bash +@test 'assert_output()' { + run echo 'have' + assert_output +} +``` + +On failure, an error message is displayed. + +``` +-- no output -- +expected non-empty output, but output was empty +-- +``` + +#### Partial matching + +Partial matching can be enabled with the `--partial` option (`-p` for +short). When used, the assertion fails if the expected *substring* is +not found in `$output`. + +```bash +@test 'assert_output() partial matching' { + run echo 'ERROR: no such file or directory' + assert_output --partial 'SUCCESS' +} +``` + +On failure, the substring and the output are displayed. + +``` +-- output does not contain substring -- +substring : SUCCESS +output : ERROR: no such file or directory +-- +``` + +This option and regular expression matching (`--regexp` or `-e`) are +mutually exclusive. An error is displayed when used simultaneously. + +#### Regular expression matching + +Regular expression matching can be enabled with the `--regexp` option +(`-e` for short). When used, the assertion fails if the *extended +regular expression* does not match `$output`. + +*Note: The anchors `^` and `$` bind to the beginning and the end of the +entire output (not individual lines), respectively.* + +```bash +@test 'assert_output() regular expression matching' { + run echo 'Foobar 0.1.0' + assert_output --regexp '^Foobar v[0-9]+\.[0-9]+\.[0-9]$' +} +``` + +On failure, the regular expression and the output are displayed. + +``` +-- regular expression does not match output -- +regexp : ^Foobar v[0-9]+\.[0-9]+\.[0-9]$ +output : Foobar 0.1.0 +-- +``` + +An error is displayed if the specified extended regular expression is +invalid. + +This option and partial matching (`--partial` or `-p`) are mutually +exclusive. An error is displayed when used simultaneously. + +#### Standard Input, HereDocs and HereStrings + +The expected output can be specified via standard input (also +heredoc/herestring) with the `-`/`--stdin` option. + +```bash +@test 'assert_output() with pipe' { + run echo 'hello' + echo 'hello' | assert_output - +} + +@test 'assert_output() with herestring' { + run echo 'hello' + assert_output - <<< hello +} +``` + + +### `refute_output` + +This function helps to verify that a command or function produces the +correct output by checking that the specified unexpected output does not +match the actual output. Matching can be literal (default), partial or +regular expression. This function is the logical complement of +`assert_output`. + +#### Literal matching + +By default, literal matching is performed. The assertion fails if +`$output` equals the unexpected output. + +```bash +@test 'refute_output()' { + run echo 'want' + refute_output 'want' +} +``` + +On failure, the output is displayed. + +``` +-- output equals, but it was expected to differ -- +output : want +-- +``` + +If output is longer than one line it is displayed in *multi-line* +format. + +#### Existence + +To assert that there is no output at all, simply omit the matching argument. + +```bash +@test 'refute_output()' { + run foo --silent + refute_output +} +``` + +On failure, an error message is displayed. + +``` +-- unexpected output -- +expected no output, but output was non-empty +-- +``` + +#### Partial matching + +Partial matching can be enabled with the `--partial` option (`-p` for +short). When used, the assertion fails if the unexpected *substring* is +found in `$output`. + +```bash +@test 'refute_output() partial matching' { + run echo 'ERROR: no such file or directory' + refute_output --partial 'ERROR' +} +``` + +On failure, the substring and the output are displayed. + +``` +-- output should not contain substring -- +substring : ERROR +output : ERROR: no such file or directory +-- +``` + +This option and regular expression matching (`--regexp` or `-e`) are +mutually exclusive. An error is displayed when used simultaneously. + +#### Regular expression matching + +Regular expression matching can be enabled with the `--regexp` option +(`-e` for short). When used, the assertion fails if the *extended +regular expression* matches `$output`. + +*Note: The anchors `^` and `$` bind to the beginning and the end of the +entire output (not individual lines), respectively.* + +```bash +@test 'refute_output() regular expression matching' { + run echo 'Foobar v0.1.0' + refute_output --regexp '^Foobar v[0-9]+\.[0-9]+\.[0-9]$' +} +``` + +On failure, the regular expression and the output are displayed. + +``` +-- regular expression should not match output -- +regexp : ^Foobar v[0-9]+\.[0-9]+\.[0-9]$ +output : Foobar v0.1.0 +-- +``` + +An error is displayed if the specified extended regular expression is +invalid. + +This option and partial matching (`--partial` or `-p`) are mutually +exclusive. An error is displayed when used simultaneously. + +#### Standard Input, HereDocs and HereStrings + +The unexpected output can be specified via standard input (also +heredoc/herestring) with the `-`/`--stdin` option. + +```bash +@test 'refute_output() with pipe' { + run echo 'hello' + echo 'world' | refute_output - +} + +@test 'refute_output() with herestring' { + run echo 'hello' + refute_output - <<< world +} +``` + + +### `assert_line` + +Similarly to `assert_output`, this function helps to verify that a +command or function produces the correct output. It checks that the +expected line appears in the output (default) or in a specific line of +it. Matching can be literal (default), partial or regular expression. +This function is the logical complement of `refute_line`. + +***Warning:*** *Due to a [bug in Bats][bats-93], empty lines are +discarded from `${lines[@]}`, causing line indices to change and +preventing testing for empty lines.* + +[bats-93]: https://github.com/sstephenson/bats/pull/93 + +#### Looking for a line in the output + +By default, the entire output is searched for the expected line. The +assertion fails if the expected line is not found in `${lines[@]}`. + +```bash +@test 'assert_line() looking for line' { + run echo $'have-0\nhave-1\nhave-2' + assert_line 'want' +} +``` + +On failure, the expected line and the output are displayed. + +***Warning:*** *The output displayed does not contain empty lines. See +the Warning above for more.* + +``` +-- output does not contain line -- +line : want +output (3 lines): + have-0 + have-1 + have-2 +-- +``` + +If output is not longer than one line, it is displayed in *two-column* +format. + +#### Matching a specific line + +When the `--index ` option is used (`-n ` for short) , the +expected line is matched only against the line identified by the given +index. The assertion fails if the expected line does not equal +`${lines[]}`. + +```bash +@test 'assert_line() specific line' { + run echo $'have-0\nhave-1\nhave-2' + assert_line --index 1 'want-1' +} +``` + +On failure, the index and the compared lines are displayed. + +``` +-- line differs -- +index : 1 +expected : want-1 +actual : have-1 +-- +``` + +#### Partial matching + +Partial matching can be enabled with the `--partial` option (`-p` for +short). When used, a match fails if the expected *substring* is not +found in the matched line. + +```bash +@test 'assert_line() partial matching' { + run echo $'have 1\nhave 2\nhave 3' + assert_line --partial 'want' +} +``` + +On failure, the same details are displayed as for literal matching, +except that the substring replaces the expected line. + +``` +-- no output line contains substring -- +substring : want +output (3 lines): + have 1 + have 2 + have 3 +-- +``` + +This option and regular expression matching (`--regexp` or `-e`) are +mutually exclusive. An error is displayed when used simultaneously. + +#### Regular expression matching + +Regular expression matching can be enabled with the `--regexp` option +(`-e` for short). When used, a match fails if the *extended regular +expression* does not match the line being tested. + +*Note: As expected, the anchors `^` and `$` bind to the beginning and +the end of the matched line, respectively.* + +```bash +@test 'assert_line() regular expression matching' { + run echo $'have-0\nhave-1\nhave-2' + assert_line --index 1 --regexp '^want-[0-9]$' +} +``` + +On failure, the same details are displayed as for literal matching, +except that the regular expression replaces the expected line. + +``` +-- regular expression does not match line -- +index : 1 +regexp : ^want-[0-9]$ +line : have-1 +-- +``` + +An error is displayed if the specified extended regular expression is +invalid. + +This option and partial matching (`--partial` or `-p`) are mutually +exclusive. An error is displayed when used simultaneously. + + +### `refute_line` + +Similarly to `refute_output`, this function helps to verify that a +command or function produces the correct output. It checks that the +unexpected line does not appear in the output (default) or in a specific +line of it. Matching can be literal (default), partial or regular +expression. This function is the logical complement of `assert_line`. + +***Warning:*** *Due to a [bug in Bats][bats-93], empty lines are +discarded from `${lines[@]}`, causing line indices to change and +preventing testing for empty lines.* + +[bats-93]: https://github.com/sstephenson/bats/pull/93 + +#### Looking for a line in the output + +By default, the entire output is searched for the unexpected line. The +assertion fails if the unexpected line is found in `${lines[@]}`. + +```bash +@test 'refute_line() looking for line' { + run echo $'have-0\nwant\nhave-2' + refute_line 'want' +} +``` + +On failure, the unexpected line, the index of its first match and the +output with the matching line highlighted are displayed. + +***Warning:*** *The output displayed does not contain empty lines. See +the Warning above for more.* + +``` +-- line should not be in output -- +line : want +index : 1 +output (3 lines): + have-0 +> want + have-2 +-- +``` + +If output is not longer than one line, it is displayed in *two-column* +format. + +#### Matching a specific line + +When the `--index ` option is used (`-n ` for short) , the +unexpected line is matched only against the line identified by the given +index. The assertion fails if the unexpected line equals +`${lines[]}`. + +```bash +@test 'refute_line() specific line' { + run echo $'have-0\nwant-1\nhave-2' + refute_line --index 1 'want-1' +} +``` + +On failure, the index and the unexpected line are displayed. + +``` +-- line should differ -- +index : 1 +line : want-1 +-- +``` + +#### Partial matching + +Partial matching can be enabled with the `--partial` option (`-p` for +short). When used, a match fails if the unexpected *substring* is found +in the matched line. + +```bash +@test 'refute_line() partial matching' { + run echo $'have 1\nwant 2\nhave 3' + refute_line --partial 'want' +} +``` + +On failure, in addition to the details of literal matching, the +substring is also displayed. When used with `--index ` the +substring replaces the unexpected line. + +``` +-- no line should contain substring -- +substring : want +index : 1 +output (3 lines): + have 1 +> want 2 + have 3 +-- +``` + +This option and regular expression matching (`--regexp` or `-e`) are +mutually exclusive. An error is displayed when used simultaneously. + +#### Regular expression matching + +Regular expression matching can be enabled with the `--regexp` option +(`-e` for short). When used, a match fails if the *extended regular +expression* matches the line being tested. + +*Note: As expected, the anchors `^` and `$` bind to the beginning and +the end of the matched line, respectively.* + +```bash +@test 'refute_line() regular expression matching' { + run echo $'Foobar v0.1.0\nRelease date: 2015-11-29' + refute_line --index 0 --regexp '^Foobar v[0-9]+\.[0-9]+\.[0-9]$' +} +``` + +On failure, in addition to the details of literal matching, the regular +expression is also displayed. When used with `--index ` the regular +expression replaces the unexpected line. + +``` +-- regular expression should not match line -- +index : 0 +regexp : ^Foobar v[0-9]+\.[0-9]+\.[0-9]$ +line : Foobar v0.1.0 +-- +``` + +An error is displayed if the specified extended regular expression is +invalid. + +This option and partial matching (`--partial` or `-p`) are mutually +exclusive. An error is displayed when used simultaneously. + + +## Options + +For functions that have options, `--` disables option parsing for the +remaining arguments to allow using arguments identical to one of the +allowed options. + +```bash +assert_output -- '-p' +``` + +Specifying `--` as an argument is similarly simple. + +```bash +refute_line -- '--' +``` + + + + +[bats]: https://github.com/sstephenson/bats +[bats-support-output]: https://github.com/ztombol/bats-support#output-formatting +[bats-support]: https://github.com/ztombol/bats-support +[bats-docs]: https://github.com/ztombol/bats-docs +[bash-comp-cmd]: https://www.gnu.org/software/bash/manual/bash.html#Compound-Commands diff --git a/stdlib/bats/tests/testfile/mods/bats-assert/load.bash b/stdlib/bats/tests/testfile/mods/bats-assert/load.bash new file mode 100644 index 00000000..ac4a875a --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-assert/load.bash @@ -0,0 +1 @@ +source "$(dirname "${BASH_SOURCE[0]}")/src/assert.bash" diff --git a/stdlib/bats/tests/testfile/mods/bats-assert/package.json b/stdlib/bats/tests/testfile/mods/bats-assert/package.json new file mode 100644 index 00000000..9a3fd991 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-assert/package.json @@ -0,0 +1,47 @@ +{ + "name": "bats-assert", + "version": "2.0.0", + "description": "Common assertions for Bats", + "homepage": "https://github.com/jasonkarns/bats-assert-1", + "license": "CC0-1.0", + "contributors": [ + "Zoltán Tömböl (https://github.com/ztombol)", + "Sam Stephenson (http://sstephenson.us/)", + "Jason Karns (http://jason.karns.name)", + "Mislav Marohnić (http://mislav.net/)", + "Tim Pope (https://github.com/tpope)" + ], + "repository": { + "type": "git", + "url": "https://github.com/jasonkarns/bats-assert-1.git" + }, + "bugs": { + "url": "https://github.com/jasonkarns/bats-assert-1/issues" + }, + "directories": { + "lib": "src", + "test": "test" + }, + "files": [ + "load.bash", + "src" + ], + "scripts": { + "postversion": "npm publish", + "prepublishOnly": "npm run publish:github", + "publish:github": "git push --follow-tags" + }, + "peerDependencies": { + "bats-support": "git+https://github.com/ztombol/bats-support.git#v0.2.0" + }, + "keywords": [ + "bats", + "bash", + "shell", + "test", + "unit", + "assert", + "assertion", + "helper" + ] +} diff --git a/stdlib/bats/tests/testfile/mods/bats-assert/src/assert.bash b/stdlib/bats/tests/testfile/mods/bats-assert/src/assert.bash new file mode 100644 index 00000000..efe069a1 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-assert/src/assert.bash @@ -0,0 +1,755 @@ +# +# bats-assert - Common assertions for Bats +# +# Written in 2016 by Zoltan Tombol +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any +# warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# . +# + +# +# assert.bash +# ----------- +# +# Assertions are functions that perform a test and output relevant +# information on failure to help debugging. They return 1 on failure +# and 0 otherwise. +# +# All output is formatted for readability using the functions of +# `output.bash' and sent to the standard error. +# + +# Fail and display the expression if it evaluates to false. +# +# NOTE: The expression must be a simple command. Compound commands, such +# as `[[', can be used only when executed with `bash -c'. +# +# Globals: +# none +# Arguments: +# $1 - expression +# Returns: +# 0 - expression evaluates to TRUE +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert() { + if ! "$@"; then + batslib_print_kv_single 10 'expression' "$*" \ + | batslib_decorate 'assertion failed' \ + | fail + fi +} + +# Fail and display the expression if it evaluates to true. +# +# NOTE: The expression must be a simple command. Compound commands, such +# as `[[', can be used only when executed with `bash -c'. +# +# Globals: +# none +# Arguments: +# $1 - expression +# Returns: +# 0 - expression evaluates to FALSE +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +refute() { + if "$@"; then + batslib_print_kv_single 10 'expression' "$*" \ + | batslib_decorate 'assertion succeeded, but it was expected to fail' \ + | fail + fi +} + +# Fail and display details if the expected and actual values do not +# equal. Details include both values. +# +# Globals: +# none +# Arguments: +# $1 - actual value +# $2 - expected value +# Returns: +# 0 - values equal +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert_equal() { + if [[ $1 != "$2" ]]; then + batslib_print_kv_single_or_multi 8 \ + 'expected' "$2" \ + 'actual' "$1" \ + | batslib_decorate 'values do not equal' \ + | fail + fi +} + +# Fail and display details if `$status' is not 0. Details include +# `$status' and `$output'. +# +# Globals: +# status +# output +# Arguments: +# none +# Returns: +# 0 - `$status' is 0 +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert_success() { + if (( status != 0 )); then + { local -ir width=6 + batslib_print_kv_single "$width" 'status' "$status" + batslib_print_kv_single_or_multi "$width" 'output' "$output" + } | batslib_decorate 'command failed' \ + | fail + fi +} + +# Fail and display details if `$status' is 0. Details include `$output'. +# +# Optionally, when the expected status is specified, fail when it does +# not equal `$status'. In this case, details include the expected and +# actual status, and `$output'. +# +# Globals: +# status +# output +# Arguments: +# $1 - [opt] expected status +# Returns: +# 0 - `$status' is not 0, or +# `$status' equals the expected status +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert_failure() { + (( $# > 0 )) && local -r expected="$1" + if (( status == 0 )); then + batslib_print_kv_single_or_multi 6 'output' "$output" \ + | batslib_decorate 'command succeeded, but it was expected to fail' \ + | fail + elif (( $# > 0 )) && (( status != expected )); then + { local -ir width=8 + batslib_print_kv_single "$width" \ + 'expected' "$expected" \ + 'actual' "$status" + batslib_print_kv_single_or_multi "$width" \ + 'output' "$output" + } | batslib_decorate 'command failed as expected, but status differs' \ + | fail + fi +} + +# Fail and display details if `$output' does not match the expected +# output. The expected output can be specified either by the first +# parameter or on the standard input. +# +# By default, literal matching is performed. The assertion fails if the +# expected output does not equal `$output'. Details include both values. +# +# Option `--partial' enables partial matching. The assertion fails if +# the expected substring cannot be found in `$output'. +# +# Option `--regexp' enables regular expression matching. The assertion +# fails if the extended regular expression does not match `$output'. An +# invalid regular expression causes an error to be displayed. +# +# It is an error to use partial and regular expression matching +# simultaneously. +# +# Globals: +# output +# Options: +# -p, --partial - partial matching +# -e, --regexp - extended regular expression matching +# -, --stdin - read expected output from the standard input +# Arguments: +# $1 - expected output +# Returns: +# 0 - expected matches the actual output +# 1 - otherwise +# Inputs: +# STDIN - [=$1] expected output +# Outputs: +# STDERR - details, on failure +# error message, on error +assert_output() { + local -i is_mode_partial=0 + local -i is_mode_regexp=0 + local -i is_mode_nonempty=0 + local -i use_stdin=0 + + # Handle options. + if (( $# == 0 )); then + is_mode_nonempty=1 + fi + + while (( $# > 0 )); do + case "$1" in + -p|--partial) is_mode_partial=1; shift ;; + -e|--regexp) is_mode_regexp=1; shift ;; + -|--stdin) use_stdin=1; shift ;; + --) shift; break ;; + *) break ;; + esac + done + + if (( is_mode_partial )) && (( is_mode_regexp )); then + echo "\`--partial' and \`--regexp' are mutually exclusive" \ + | batslib_decorate 'ERROR: assert_output' \ + | fail + return $? + fi + + # Arguments. + local expected + if (( use_stdin )); then + expected="$(cat -)" + else + expected="$1" + fi + + # Matching. + if (( is_mode_nonempty )); then + if [ -z "$output" ]; then + echo 'expected non-empty output, but output was empty' \ + | batslib_decorate 'no output' \ + | fail + fi + elif (( is_mode_regexp )); then + if [[ '' =~ $expected ]] || (( $? == 2 )); then + echo "Invalid extended regular expression: \`$expected'" \ + | batslib_decorate 'ERROR: assert_output' \ + | fail + elif ! [[ $output =~ $expected ]]; then + batslib_print_kv_single_or_multi 6 \ + 'regexp' "$expected" \ + 'output' "$output" \ + | batslib_decorate 'regular expression does not match output' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ $output != *"$expected"* ]]; then + batslib_print_kv_single_or_multi 9 \ + 'substring' "$expected" \ + 'output' "$output" \ + | batslib_decorate 'output does not contain substring' \ + | fail + fi + else + if [[ $output != "$expected" ]]; then + batslib_print_kv_single_or_multi 8 \ + 'expected' "$expected" \ + 'actual' "$output" \ + | batslib_decorate 'output differs' \ + | fail + fi + fi +} + +# Fail and display details if `$output' matches the unexpected output. +# The unexpected output can be specified either by the first parameter +# or on the standard input. +# +# By default, literal matching is performed. The assertion fails if the +# unexpected output equals `$output'. Details include `$output'. +# +# Option `--partial' enables partial matching. The assertion fails if +# the unexpected substring is found in `$output'. The unexpected +# substring is added to details. +# +# Option `--regexp' enables regular expression matching. The assertion +# fails if the extended regular expression does matches `$output'. The +# regular expression is added to details. An invalid regular expression +# causes an error to be displayed. +# +# It is an error to use partial and regular expression matching +# simultaneously. +# +# Globals: +# output +# Options: +# -p, --partial - partial matching +# -e, --regexp - extended regular expression matching +# -, --stdin - read unexpected output from the standard input +# Arguments: +# $1 - unexpected output +# Returns: +# 0 - unexpected matches the actual output +# 1 - otherwise +# Inputs: +# STDIN - [=$1] unexpected output +# Outputs: +# STDERR - details, on failure +# error message, on error +refute_output() { + local -i is_mode_partial=0 + local -i is_mode_regexp=0 + local -i is_mode_empty=0 + local -i use_stdin=0 + + # Handle options. + if (( $# == 0 )); then + is_mode_empty=1 + fi + + while (( $# > 0 )); do + case "$1" in + -p|--partial) is_mode_partial=1; shift ;; + -e|--regexp) is_mode_regexp=1; shift ;; + -|--stdin) use_stdin=1; shift ;; + --) shift; break ;; + *) break ;; + esac + done + + if (( is_mode_partial )) && (( is_mode_regexp )); then + echo "\`--partial' and \`--regexp' are mutually exclusive" \ + | batslib_decorate 'ERROR: refute_output' \ + | fail + return $? + fi + + # Arguments. + local unexpected + if (( use_stdin )); then + unexpected="$(cat -)" + else + unexpected="$1" + fi + + if (( is_mode_regexp == 1 )) && [[ '' =~ $unexpected ]] || (( $? == 2 )); then + echo "Invalid extended regular expression: \`$unexpected'" \ + | batslib_decorate 'ERROR: refute_output' \ + | fail + return $? + fi + + # Matching. + if (( is_mode_empty )); then + if [ -n "$output" ]; then + batslib_print_kv_single_or_multi 6 \ + 'output' "$output" \ + | batslib_decorate 'output non-empty, but expected no output' \ + | fail + fi + elif (( is_mode_regexp )); then + if [[ $output =~ $unexpected ]] || (( $? == 0 )); then + batslib_print_kv_single_or_multi 6 \ + 'regexp' "$unexpected" \ + 'output' "$output" \ + | batslib_decorate 'regular expression should not match output' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ $output == *"$unexpected"* ]]; then + batslib_print_kv_single_or_multi 9 \ + 'substring' "$unexpected" \ + 'output' "$output" \ + | batslib_decorate 'output should not contain substring' \ + | fail + fi + else + if [[ $output == "$unexpected" ]]; then + batslib_print_kv_single_or_multi 6 \ + 'output' "$output" \ + | batslib_decorate 'output equals, but it was expected to differ' \ + | fail + fi + fi +} + +# Fail and display details if the expected line is not found in the +# output (default) or in a specific line of it. +# +# By default, the entire output is searched for the expected line. The +# expected line is matched against every element of `${lines[@]}'. If no +# match is found, the assertion fails. Details include the expected line +# and `${lines[@]}'. +# +# When `--index ' is specified, only the -th line is matched. +# If the expected line does not match `${lines[]}', the assertion +# fails. Details include and the compared lines. +# +# By default, literal matching is performed. A literal match fails if +# the expected string does not equal the matched string. +# +# Option `--partial' enables partial matching. A partial match fails if +# the expected substring is not found in the target string. +# +# Option `--regexp' enables regular expression matching. A regular +# expression match fails if the extended regular expression does not +# match the target string. An invalid regular expression causes an error +# to be displayed. +# +# It is an error to use partial and regular expression matching +# simultaneously. +# +# Mandatory arguments to long options are mandatory for short options +# too. +# +# Globals: +# output +# lines +# Options: +# -n, --index - match the -th line +# -p, --partial - partial matching +# -e, --regexp - extended regular expression matching +# Arguments: +# $1 - expected line +# Returns: +# 0 - match found +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +# error message, on error +# FIXME(ztombol): Display `${lines[@]}' instead of `$output'! +assert_line() { + local -i is_match_line=0 + local -i is_mode_partial=0 + local -i is_mode_regexp=0 + + # Handle options. + while (( $# > 0 )); do + case "$1" in + -n|--index) + if (( $# < 2 )) || ! [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then + echo "\`--index' requires an integer argument: \`$2'" \ + | batslib_decorate 'ERROR: assert_line' \ + | fail + return $? + fi + is_match_line=1 + local -ri idx="$2" + shift 2 + ;; + -p|--partial) is_mode_partial=1; shift ;; + -e|--regexp) is_mode_regexp=1; shift ;; + --) shift; break ;; + *) break ;; + esac + done + + if (( is_mode_partial )) && (( is_mode_regexp )); then + echo "\`--partial' and \`--regexp' are mutually exclusive" \ + | batslib_decorate 'ERROR: assert_line' \ + | fail + return $? + fi + + # Arguments. + local -r expected="$1" + + if (( is_mode_regexp == 1 )) && [[ '' =~ $expected ]] || (( $? == 2 )); then + echo "Invalid extended regular expression: \`$expected'" \ + | batslib_decorate 'ERROR: assert_line' \ + | fail + return $? + fi + + # Matching. + if (( is_match_line )); then + # Specific line. + if (( is_mode_regexp )); then + if ! [[ ${lines[$idx]} =~ $expected ]]; then + batslib_print_kv_single 6 \ + 'index' "$idx" \ + 'regexp' "$expected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'regular expression does not match line' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ ${lines[$idx]} != *"$expected"* ]]; then + batslib_print_kv_single 9 \ + 'index' "$idx" \ + 'substring' "$expected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'line does not contain substring' \ + | fail + fi + else + if [[ ${lines[$idx]} != "$expected" ]]; then + batslib_print_kv_single 8 \ + 'index' "$idx" \ + 'expected' "$expected" \ + 'actual' "${lines[$idx]}" \ + | batslib_decorate 'line differs' \ + | fail + fi + fi + else + # Contained in output. + if (( is_mode_regexp )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + [[ ${lines[$idx]} =~ $expected ]] && return 0 + done + { local -ar single=( + 'regexp' "$expected" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'no output line matches regular expression' \ + | fail + elif (( is_mode_partial )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + [[ ${lines[$idx]} == *"$expected"* ]] && return 0 + done + { local -ar single=( + 'substring' "$expected" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'no output line contains substring' \ + | fail + else + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + [[ ${lines[$idx]} == "$expected" ]] && return 0 + done + { local -ar single=( + 'line' "$expected" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'output does not contain line' \ + | fail + fi + fi +} + +# Fail and display details if the unexpected line is found in the output +# (default) or in a specific line of it. +# +# By default, the entire output is searched for the unexpected line. The +# unexpected line is matched against every element of `${lines[@]}'. If +# a match is found, the assertion fails. Details include the unexpected +# line, the index of the first match and `${lines[@]}' with the matching +# line highlighted if `${lines[@]}' is longer than one line. +# +# When `--index ' is specified, only the -th line is matched. +# If the unexpected line matches `${lines[]}', the assertion fails. +# Details include and the unexpected line. +# +# By default, literal matching is performed. A literal match fails if +# the unexpected string does not equal the matched string. +# +# Option `--partial' enables partial matching. A partial match fails if +# the unexpected substring is found in the target string. When used with +# `--index ', the unexpected substring is also displayed on +# failure. +# +# Option `--regexp' enables regular expression matching. A regular +# expression match fails if the extended regular expression matches the +# target string. When used with `--index ', the regular expression +# is also displayed on failure. An invalid regular expression causes an +# error to be displayed. +# +# It is an error to use partial and regular expression matching +# simultaneously. +# +# Mandatory arguments to long options are mandatory for short options +# too. +# +# Globals: +# output +# lines +# Options: +# -n, --index - match the -th line +# -p, --partial - partial matching +# -e, --regexp - extended regular expression matching +# Arguments: +# $1 - unexpected line +# Returns: +# 0 - match not found +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +# error message, on error +# FIXME(ztombol): Display `${lines[@]}' instead of `$output'! +refute_line() { + local -i is_match_line=0 + local -i is_mode_partial=0 + local -i is_mode_regexp=0 + + # Handle options. + while (( $# > 0 )); do + case "$1" in + -n|--index) + if (( $# < 2 )) || ! [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then + echo "\`--index' requires an integer argument: \`$2'" \ + | batslib_decorate 'ERROR: refute_line' \ + | fail + return $? + fi + is_match_line=1 + local -ri idx="$2" + shift 2 + ;; + -p|--partial) is_mode_partial=1; shift ;; + -e|--regexp) is_mode_regexp=1; shift ;; + --) shift; break ;; + *) break ;; + esac + done + + if (( is_mode_partial )) && (( is_mode_regexp )); then + echo "\`--partial' and \`--regexp' are mutually exclusive" \ + | batslib_decorate 'ERROR: refute_line' \ + | fail + return $? + fi + + # Arguments. + local -r unexpected="$1" + + if (( is_mode_regexp == 1 )) && [[ '' =~ $unexpected ]] || (( $? == 2 )); then + echo "Invalid extended regular expression: \`$unexpected'" \ + | batslib_decorate 'ERROR: refute_line' \ + | fail + return $? + fi + + # Matching. + if (( is_match_line )); then + # Specific line. + if (( is_mode_regexp )); then + if [[ ${lines[$idx]} =~ $unexpected ]] || (( $? == 0 )); then + batslib_print_kv_single 6 \ + 'index' "$idx" \ + 'regexp' "$unexpected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'regular expression should not match line' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ ${lines[$idx]} == *"$unexpected"* ]]; then + batslib_print_kv_single 9 \ + 'index' "$idx" \ + 'substring' "$unexpected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'line should not contain substring' \ + | fail + fi + else + if [[ ${lines[$idx]} == "$unexpected" ]]; then + batslib_print_kv_single 5 \ + 'index' "$idx" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'line should differ' \ + | fail + fi + fi + else + # Line contained in output. + if (( is_mode_regexp )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + if [[ ${lines[$idx]} =~ $unexpected ]]; then + { local -ar single=( + 'regexp' "$unexpected" + 'index' "$idx" + ) + local -a may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + if batslib_is_single_line "${may_be_multi[1]}"; then + batslib_print_kv_single "$width" "${may_be_multi[@]}" + else + may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ + | batslib_prefix \ + | batslib_mark '>' "$idx" )" + batslib_print_kv_multi "${may_be_multi[@]}" + fi + } | batslib_decorate 'no line should match the regular expression' \ + | fail + return $? + fi + done + elif (( is_mode_partial )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + if [[ ${lines[$idx]} == *"$unexpected"* ]]; then + { local -ar single=( + 'substring' "$unexpected" + 'index' "$idx" + ) + local -a may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + if batslib_is_single_line "${may_be_multi[1]}"; then + batslib_print_kv_single "$width" "${may_be_multi[@]}" + else + may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ + | batslib_prefix \ + | batslib_mark '>' "$idx" )" + batslib_print_kv_multi "${may_be_multi[@]}" + fi + } | batslib_decorate 'no line should contain substring' \ + | fail + return $? + fi + done + else + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + if [[ ${lines[$idx]} == "$unexpected" ]]; then + { local -ar single=( + 'line' "$unexpected" + 'index' "$idx" + ) + local -a may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + if batslib_is_single_line "${may_be_multi[1]}"; then + batslib_print_kv_single "$width" "${may_be_multi[@]}" + else + may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ + | batslib_prefix \ + | batslib_mark '>' "$idx" )" + batslib_print_kv_multi "${may_be_multi[@]}" + fi + } | batslib_decorate 'line should not be in output' \ + | fail + return $? + fi + done + fi + fi +} diff --git a/stdlib/bats/tests/testfile/mods/bats-support/.travis.yml b/stdlib/bats/tests/testfile/mods/bats-support/.travis.yml new file mode 100644 index 00000000..75721f28 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/.travis.yml @@ -0,0 +1,7 @@ +language: bash +before_install: + - ./script/install-bats.sh +before_script: + - export PATH="${HOME}/.local/bin:${PATH}" +script: + - bats test diff --git a/stdlib/bats/tests/testfile/mods/bats-support/CHANGELOG.md b/stdlib/bats/tests/testfile/mods/bats-support/CHANGELOG.md new file mode 100644 index 00000000..3ac6fbcb --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/CHANGELOG.md @@ -0,0 +1,37 @@ +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + + +## [0.2.0] - 2016-03-22 + +### Added + +- `npm` support +- Reporting arbitrary failures with `fail()` (moved from `bats-assert`) + +### Changed + +- Library renamed to `bats-support` + + +## 0.1.0 - 2016-02-16 + +### Added + +- Two-column key-value formatting with `batslib_print_kv_single()` +- Multi-line key-value formatting with `batslib_print_kv_multi()` +- Mixed formatting with `batslib_print_kv_single_or_multi()` +- Header and footer decoration with `batslib_decorate()` +- Prefixing lines with `batslib_prefix()` +- Marking lines with `batslib_mark()` +- Common output function `batslib_err()` +- Line counting with `batslib_count_lines()` +- Checking whether a text is one line long with + `batslib_is_single_line()` +- Determining key width for two-column and mixed formatting with + `batslib_get_max_single_line_key_width()` + + +[0.2.0]: https://github.com/ztombol/bats-support/compare/v0.1.0...v0.2.0 diff --git a/stdlib/bats/tests/testfile/mods/bats-support/LICENSE b/stdlib/bats/tests/testfile/mods/bats-support/LICENSE new file mode 100644 index 00000000..670154e3 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/LICENSE @@ -0,0 +1,116 @@ +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + diff --git a/stdlib/bats/tests/testfile/mods/bats-support/README.md b/stdlib/bats/tests/testfile/mods/bats-support/README.md new file mode 100644 index 00000000..cd3fee17 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/README.md @@ -0,0 +1,128 @@ +*__Important:__ `bats-core` has been renamed to `bats-support`. GitHub +automatically redirects all references, e.g. submodules and clones will +continue to work, but you are encouraged to [update][github-rename] +them. Version numbering continues where `bats-core` left off.* + +[github-rename]: https://help.github.com/articles/renaming-a-repository/ + +- - - - - + +# bats-support + +[![GitHub license](https://img.shields.io/badge/license-CC0-blue.svg)](https://raw.githubusercontent.com/ztombol/bats-support/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/ztombol/bats-support.svg)](https://github.com/ztombol/bats-support/releases/latest) +[![Build Status](https://travis-ci.org/ztombol/bats-support.svg?branch=master)](https://travis-ci.org/ztombol/bats-support) + +`bats-support` is a supporting library providing common functions to +test helper libraries written for [Bats][bats]. + +Features: +- [error reporting](#error-reporting) +- [output formatting](#output-formatting) + +See the [shared documentation][bats-docs] to learn how to install and +load this library. + +If you want to use this library in your own helpers or just want to +learn about its internals see the developer documentation in the [source +files](src). + + +## Error reporting + +### `fail` + +Display an error message and fail. This function provides a convenient +way to report failure in arbitrary situations. You can use it to +implement your own helpers when the ones available do not meet your +needs. Other functions use it internally as well. + +```bash +@test 'fail()' { + fail 'this test always fails' +} +``` + +The message can also be specified on the standard input. + +```bash +@test 'fail() with pipe' { + echo 'this test always fails' | fail +} +``` + +This function always fails and simply outputs the given message. + +``` +this test always fails +``` + + +## Output formatting + +Many test helpers need to produce human readable output. This library +provides a simple way to format simple messages and key value pairs, and +display them on the standard error. + + +### Simple message + +Simple messages without structure, e.g. one-line error messages, are +simply wrapped in a header and a footer to help them stand out. + +``` +-- ERROR: assert_output -- +`--partial' and `--regexp' are mutually exclusive +-- +``` + + +### Key-Value pairs + +Some helpers, e.g. [assertions][bats-assert], structure output as +key-value pairs. This library provides two ways to format them. + +When the value is one line long, a pair can be displayed in a columnar +fashion called ***two-column*** format. + +``` +-- output differs -- +expected : want +actual : have +-- +``` + +When the value is longer than one line, the key and value must be +displayed on separate lines. First, the key is displayed along with the +number of lines in the value. Then, the value, indented by two spaces +for added readability, starting on the next line. This is called +***multi-line*** format. + +``` +-- command failed -- +status : 1 +output (2 lines): + Error! Something went terribly wrong! + Our engineers are panicing... \`>`;/ +-- +``` + +Sometimes, for clarity, it is a good idea to display related values also +in this format, even if they are just one line long. + +``` +-- output differs -- +expected (1 lines): + want +actual (3 lines): + have 1 + have 2 + have 3 +-- +``` + + + +[bats]: https://github.com/sstephenson/bats +[bats-docs]: https://github.com/ztombol/bats-docs +[bats-assert]: https://github.com/ztombol/bats-assert diff --git a/stdlib/bats/tests/testfile/mods/bats-support/load.bash b/stdlib/bats/tests/testfile/mods/bats-support/load.bash new file mode 100644 index 00000000..0d4a5ac9 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/load.bash @@ -0,0 +1,2 @@ +source "$(dirname "${BASH_SOURCE[0]}")/src/output.bash" +source "$(dirname "${BASH_SOURCE[0]}")/src/error.bash" diff --git a/stdlib/bats/tests/testfile/mods/bats-support/package.json b/stdlib/bats/tests/testfile/mods/bats-support/package.json new file mode 100644 index 00000000..ac1128dc --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/package.json @@ -0,0 +1,5 @@ +{ + "name": "bats-support", + "version": "0.2.0", + "private": true +} diff --git a/stdlib/bats/tests/testfile/mods/bats-support/script/install-bats.sh b/stdlib/bats/tests/testfile/mods/bats-support/script/install-bats.sh new file mode 100755 index 00000000..4c3161a4 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/script/install-bats.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -o errexit +set -o xtrace + +git clone --depth 1 https://github.com/sstephenson/bats +cd bats && ./install.sh "${HOME}/.local" && cd .. && rm -rf bats diff --git a/stdlib/bats/tests/testfile/mods/bats-support/src/error.bash b/stdlib/bats/tests/testfile/mods/bats-support/src/error.bash new file mode 100644 index 00000000..e5d97912 --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/src/error.bash @@ -0,0 +1,41 @@ +# +# bats-support - Supporting library for Bats test helpers +# +# Written in 2016 by Zoltan Tombol +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any +# warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# . +# + +# +# error.bash +# ---------- +# +# Functions implementing error reporting. Used by public helper +# functions or test suits directly. +# + +# Fail and display a message. When no parameters are specified, the +# message is read from the standard input. Other functions use this to +# report failure. +# +# Globals: +# none +# Arguments: +# $@ - [=STDIN] message +# Returns: +# 1 - always +# Inputs: +# STDIN - [=$@] message +# Outputs: +# STDERR - message +fail() { + (( $# == 0 )) && batslib_err || batslib_err "$@" + return 1 +} diff --git a/stdlib/bats/tests/testfile/mods/bats-support/src/output.bash b/stdlib/bats/tests/testfile/mods/bats-support/src/output.bash new file mode 100644 index 00000000..c6cf6a6b --- /dev/null +++ b/stdlib/bats/tests/testfile/mods/bats-support/src/output.bash @@ -0,0 +1,279 @@ +# +# bats-support - Supporting library for Bats test helpers +# +# Written in 2016 by Zoltan Tombol +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any +# warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# . +# + +# +# output.bash +# ----------- +# +# Private functions implementing output formatting. Used by public +# helper functions. +# + +# Print a message to the standard error. When no parameters are +# specified, the message is read from the standard input. +# +# Globals: +# none +# Arguments: +# $@ - [=STDIN] message +# Returns: +# none +# Inputs: +# STDIN - [=$@] message +# Outputs: +# STDERR - message +batslib_err() { + { if (( $# > 0 )); then + echo "$@" + else + cat - + fi + } >&2 +} + +# Count the number of lines in the given string. +# +# TODO(ztombol): Fix tests and remove this note after #93 is resolved! +# NOTE: Due to a bug in Bats, `batslib_count_lines "$output"' does not +# give the same result as `${#lines[@]}' when the output contains +# empty lines. +# See PR #93 (https://github.com/sstephenson/bats/pull/93). +# +# Globals: +# none +# Arguments: +# $1 - string +# Returns: +# none +# Outputs: +# STDOUT - number of lines +batslib_count_lines() { + local -i n_lines=0 + local line + while IFS='' read -r line || [[ -n $line ]]; do + (( ++n_lines )) + done < <(printf '%s' "$1") + echo "$n_lines" +} + +# Determine whether all strings are single-line. +# +# Globals: +# none +# Arguments: +# $@ - strings +# Returns: +# 0 - all strings are single-line +# 1 - otherwise +batslib_is_single_line() { + for string in "$@"; do + (( $(batslib_count_lines "$string") > 1 )) && return 1 + done + return 0 +} + +# Determine the length of the longest key that has a single-line value. +# +# This function is useful in determining the correct width of the key +# column in two-column format when some keys may have multi-line values +# and thus should be excluded. +# +# Globals: +# none +# Arguments: +# $odd - key +# $even - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - length of longest key +batslib_get_max_single_line_key_width() { + local -i max_len=-1 + while (( $# != 0 )); do + local -i key_len="${#1}" + batslib_is_single_line "$2" && (( key_len > max_len )) && max_len="$key_len" + shift 2 + done + echo "$max_len" +} + +# Print key-value pairs in two-column format. +# +# Keys are displayed in the first column, and their corresponding values +# in the second. To evenly line up values, the key column is fixed-width +# and its width is specified with the first parameter (possibly computed +# using `batslib_get_max_single_line_key_width'). +# +# Globals: +# none +# Arguments: +# $1 - width of key column +# $even - key +# $odd - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - formatted key-value pairs +batslib_print_kv_single() { + local -ir col_width="$1"; shift + while (( $# != 0 )); do + printf '%-*s : %s\n' "$col_width" "$1" "$2" + shift 2 + done +} + +# Print key-value pairs in multi-line format. +# +# The key is displayed first with the number of lines of its +# corresponding value in parenthesis. Next, starting on the next line, +# the value is displayed. For better readability, it is recommended to +# indent values using `batslib_prefix'. +# +# Globals: +# none +# Arguments: +# $odd - key +# $even - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - formatted key-value pairs +batslib_print_kv_multi() { + while (( $# != 0 )); do + printf '%s (%d lines):\n' "$1" "$( batslib_count_lines "$2" )" + printf '%s\n' "$2" + shift 2 + done +} + +# Print all key-value pairs in either two-column or multi-line format +# depending on whether all values are single-line. +# +# If all values are single-line, print all pairs in two-column format +# with the specified key column width (identical to using +# `batslib_print_kv_single'). +# +# Otherwise, print all pairs in multi-line format after indenting values +# with two spaces for readability (identical to using `batslib_prefix' +# and `batslib_print_kv_multi') +# +# Globals: +# none +# Arguments: +# $1 - width of key column (for two-column format) +# $even - key +# $odd - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - formatted key-value pairs +batslib_print_kv_single_or_multi() { + local -ir width="$1"; shift + local -a pairs=( "$@" ) + + local -a values=() + local -i i + for (( i=1; i < ${#pairs[@]}; i+=2 )); do + values+=( "${pairs[$i]}" ) + done + + if batslib_is_single_line "${values[@]}"; then + batslib_print_kv_single "$width" "${pairs[@]}" + else + local -i i + for (( i=1; i < ${#pairs[@]}; i+=2 )); do + pairs[$i]="$( batslib_prefix < <(printf '%s' "${pairs[$i]}") )" + done + batslib_print_kv_multi "${pairs[@]}" + fi +} + +# Prefix each line read from the standard input with the given string. +# +# Globals: +# none +# Arguments: +# $1 - [= ] prefix string +# Returns: +# none +# Inputs: +# STDIN - lines +# Outputs: +# STDOUT - prefixed lines +batslib_prefix() { + local -r prefix="${1:- }" + local line + while IFS='' read -r line || [[ -n $line ]]; do + printf '%s%s\n' "$prefix" "$line" + done +} + +# Mark select lines of the text read from the standard input by +# overwriting their beginning with the given string. +# +# Usually the input is indented by a few spaces using `batslib_prefix' +# first. +# +# Globals: +# none +# Arguments: +# $1 - marking string +# $@ - indices (zero-based) of lines to mark +# Returns: +# none +# Inputs: +# STDIN - lines +# Outputs: +# STDOUT - lines after marking +batslib_mark() { + local -r symbol="$1"; shift + # Sort line numbers. + set -- $( sort -nu <<< "$( printf '%d\n' "$@" )" ) + + local line + local -i idx=0 + while IFS='' read -r line || [[ -n $line ]]; do + if (( ${1:--1} == idx )); then + printf '%s\n' "${symbol}${line:${#symbol}}" + shift + else + printf '%s\n' "$line" + fi + (( ++idx )) + done +} + +# Enclose the input text in header and footer lines. +# +# The header contains the given string as title. The output is preceded +# and followed by an additional newline to make it stand out more. +# +# Globals: +# none +# Arguments: +# $1 - title +# Returns: +# none +# Inputs: +# STDIN - text +# Outputs: +# STDOUT - decorated text +batslib_decorate() { + echo + echo "-- $1 --" + cat - + echo '--' + echo +} diff --git a/stdlib/bats/tests/testfile/package-lock.json b/stdlib/bats/tests/testfile/package-lock.json deleted file mode 100644 index bafb8de0..00000000 --- a/stdlib/bats/tests/testfile/package-lock.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "npm", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "bats-assert": "^2.0.0", - "bats-support": "^0.2.0" - } - }, - "node_modules/bats-assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bats-assert/-/bats-assert-2.0.0.tgz", - "integrity": "sha512-qO3kNilWxW8iCONu9NDUfvsCiC6JzL6DPOc/DGq9z3bZ9/A7wURJ+FnFMxGbofOmWbCoy7pVhofn0o47A95qkQ==", - "peerDependencies": { - "bats-support": "git+https://github.com/ztombol/bats-support.git#v0.2.0" - } - }, - "node_modules/bats-support": { - "version": "0.2.0", - "resolved": "git+ssh://git@github.com/ztombol/bats-support.git#d0a131831c487a1f1141e76d3ab386c89642cdff" - } - }, - "dependencies": { - "bats-assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bats-assert/-/bats-assert-2.0.0.tgz", - "integrity": "sha512-qO3kNilWxW8iCONu9NDUfvsCiC6JzL6DPOc/DGq9z3bZ9/A7wURJ+FnFMxGbofOmWbCoy7pVhofn0o47A95qkQ==", - "requires": {} - }, - "bats-support": { - "version": "git+ssh://git@github.com/ztombol/bats-support.git#d0a131831c487a1f1141e76d3ab386c89642cdff", - "from": "bats-support@*" - } - } -} diff --git a/stdlib/bats/tests/testfile/package.json b/stdlib/bats/tests/testfile/package.json deleted file mode 100644 index 0a03f60e..00000000 --- a/stdlib/bats/tests/testfile/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "bats-assert": "^2.0.0", - "bats-support": "^0.2.0" - } -} diff --git a/stdlib/bats/tests/testfile/test.bats b/stdlib/bats/tests/testfile/test.bats index baea66b7..a7dcfe33 100644 --- a/stdlib/bats/tests/testfile/test.bats +++ b/stdlib/bats/tests/testfile/test.bats @@ -1,6 +1,6 @@ setup() { - load 'node_modules/bats-support/load' - load 'node_modules/bats-assert/load' + load 'mods/bats-support/load' + load 'mods/bats-assert/load' } @test "simple bats test" {