bats-file icon indicating copy to clipboard operation
bats-file copied to clipboard

Assertions are inconsistent with and more limited than bats-assert

Open inkarkat opened this issue 11 months ago • 1 comments

I've started using bats-assert and am now looking into how bats-file can help with file-based assertions. As both libraries are built on bats-support (and have originated from the same author), I see these as closely related projects, and expect consistency in their APIs. However, there seem to be differences that make adoption harder:

  • bats-assert uses assert and refute to distinguish between positive and negative assertions, whereas bats-file uses assert_something and assert_not_something. For example, assert_file_not_exists should be named refute_file_exists to be consistent with bats-assert.
  • Some negative assertions are missing, e.g. there's no assert_file_size_not_equals (or rather refute_file_size_equals), and no refute_files_equal.
  • assert_file_contains only does regexp matching; the related assert_output from bats-assert offers complete equivalence, partial (but literal) matching, and regexp matching, making it far more versatile.

All of bats-file's assertions are thin wrappers around test commands; its main value is in providing a fluent, consistent, and discoverable API. I suggest to align the API with bats-assert, and to add the missing negative assertions and more matching options to assert_file_contains. This would make the library more powerful and easier to use for users already familiar with bats-assert.

inkarkat avatar Jan 04 '25 11:01 inkarkat

The thin wrapper & only having regexp matching also causes footguns when trying to match a string with backslashes.

For a concrete example, a current project I'm working on involves a Bash script that writes another Bash script out from some simple templates. There's a line in my script doing printf %q in order to generate a bash-quoted string, which turns 'foo bar' into foo\ bar.

If I use assert_file_contains my_script_output.sh 'foo\ bar', the test fails, because grep tries to interpret the backslash escape -- I need to instead write assert_file_contains my_script_output.sh 'foo\\ bar', which is more than a little uncomfortable.

I'll probably switch to reading the file contents into a variable and using bats-assert for now.

EDIT: originally I referred to this behavior as a bug, but it really is just a result of being a regexp match, so I rephrased my complaint to call this behavior a footgun instead.

b- avatar Feb 04 '25 23:02 b-