This is part of the effort to improve performance by reducing the number
of command substitutions/subshells spawned by `bats_debug_trap`.
Under Bash 3.2.57(1)-release on a MacBook Pro with a 2.9GHz Intel Core
i5 CPU and 8GB 1867MHz DDR3 RAM, this makes `bin/bats test/` go from the
following for the previous commit:
44 tests, 0 failures
real 0m5.293s
user 0m2.853s
sys 0m2.087s
to:
real 0m4.319s
user 0m2.559s
sys 0m1.454s
This is part of the effort to improve performance by reducing the number
of command substitutions/subshells spawned by `bats_debug_trap`.
Under Bash 3.2.57(1)-release on a MacBook Pro with a 2.9GHz Intel Core
i5 CPU and 8GB 1867MHz DDR3 RAM, this makes `bin/bats test/` go from:
44 tests, 0 failures
real 0m7.565s
user 0m3.664s
sys 0m3.368s
to:
real 0m6.449s
user 0m3.290s
sys 0m2.665s
When running under Bash 3.2.57(1)-release on macOS, the following tests
would fail because `BATS_ERROR_STACK_TRACE` would be empty, and hence no
information about the actual error would get printed:
- one failing test
- failing test with significant status
- failing test file outside of BATS_CWD
This is because each of these cases use `FIXTURE_ROOT/failing.bats`, and
the `ERR` trap would not fire for its `eval "( exit ${STATUS:-1} )"`
line. Changing it to `exit ${STATUS:-1}` produced the same effect, and
changing it to `return ${STATUS:-1}` would cause the output to point to
the previous line, which executes `true`.
However, the correct status would be reported to the `EXIT` trap, so now
we call `bats_error_trap` at the very beginning of `bats_teardown_trap`.
All the existing tests now pass under Bash 3.2.57(1)-release, Bash
4.2.25(1)-release (the version from the default Ubuntu 12.04.5/Precise
image on Travis CI), and Bash 4.4.12(1)-release.
IFS was modified by run() becoming '\n' and so relying to its bash default
was failing tests.
Also some wrong tests corrected because was relying on this behavior to pass.
Fix#89
The outermost command—i.e. the line that failed inside the test case function itself—is more likely to be meaningful at a glance than the innermost command, which might be e.g. the implementation of a helper assertion.
Tested on GNU `sed --posix`.
From `info sed`:
`\+'
As `*', but matches one or more. It is a GNU extension.
`\CHAR'
Matches CHAR, where CHAR is one of `$', `*', `.', `[', `\', or `^'.
Note that the only C-like backslash sequences that you can
portably assume to be interpreted are `\n' and `\\'; in particular
`\t' is not portable, and matches a `t' under most implementations
of `sed', rather than a tab character.
The `((x++))` syntax is shorthand for `let x++`. According to `help let`:
If the last ARG evaluates to 0, let returns 1; 0 is returned
otherwise.
Thus the exit status of the expression `x=0; let x++` is 1, since the post-increment `++` operator evaluates to the value of the variable before incrementing.
In Bash 4, this non-zero exit status properly triggers `set -e`'s error trap, but in Bash 3 it does not. That's why the tests were passing on OS X (Bash 3) but not Linux (Bash 4).
We can work around the problem by choosing an incrementation expression that never evaluates to 0, such as `+=` or the pre-increment `++` operator. For consistency and clarity, I've changed to `x+=1` everywhere.
Ref. #25, #27