Closed lanyou0 closed 1 week ago
Hi, @lanyou0. I am not sure what you mean. Sourcing other scripts should work as usual. Can you provide a code snippet example that can help us reproduce the bug?
Thank you for answering here's a snippet:
external.sh `
export MY_VARIABLE="Hello, World!"
echo "Sourced external.sh"
script.sh:
#!/bin/bash
source ./external.sh
help() {
echo "Usage: script.sh [options]"
exit 1 }
test.sh
function set_up() {
source 'script.sh' }
function test_help() {
result="$(help)"
assert_exit_code "1" }
The test.sh is run through ./bashunit test.sh as mentioned in the documentation on the website
When I do that the assertion is passing but the test itself is failing because of having source, echo, and export being outside of functions. The tests pass normally if I remove all three but my problem is I have more lengthy files with a lot more sourcing and export commands so I wanted to make sure the framework is compatible before moving forward
Can you try renaming in your script.sh
your function help
to other name (eg: my_help
)?
```bash #!/bin/bash # test.sh function set_up() { source './script.sh' } function test_help() { local result result="$(my_help)" assert_exit_code 1 } ##################### #!/bin/bash # script.sh source ./external.sh my_help() { echo "Usage: script.sh [options]" exit 1 } ##################### #!/bin/bash # external.sh export MY_VARIABLE="Hello, World!" echo "Sourced external.sh" ```
For me this works. Can you let me know if you can reproduce the same or you got any issues, @lanyou0?
Hello, for some reason it is still failing, and I have tried the exact code you provided with the changes to help
@lanyou0 from where are you running ./bashunit
? I am testing it with all these files inside a common directory named local
and ./bashunit
is at the root of the project. When being inside the same directory of those files, then it's working. But if I am outside, then it's not working. Do you have the same behavior? I am trying to understand your case to reproduce the same problem, otherwise it is pretty hard for me to fix it.
Suggestions that can help me reproduce it:
main
.@lanyou0 can you change in your test.sh
the set_up()
to make sure the script.sh is loaded with a relative path?
_ROOT_DIR="$(dirname "${BASH_SOURCE[0]}")"
function set_up() {
source "$_ROOT_DIR/script.sh"
}
UPDATE: Check this example: https://github.com/TypedDevs/bashunit/blob/main/example/custom_functions_test.sh#L5
Hello, thank you for your help: Basically, I downloaded the bashunit framework using the following command: curl -s https://bashunit.typeddevs.com/install.sh | bash, which gives me the newest version, and added it onto a folder called bashunit_tests where I have my test.sh file. I added the external.sh and script.sh files in a different directory and the test seems to pass if:
However this framework is a bit confusing since if I try to do this in my script.sh
with external.sh having:
my test.sh passes:
but if I remove # echo "$(dirname)" from script.sh, my test fails
Sorry if this seems confusing I am just trying to debug as much as I can
I can reproduce the error 🤔 weird weird... with the echo "$(dirname)"
but removing it (commenting it out) then it fails, wtf 🤣
CC: @khru @antonio-gg-dev @cmayo
Yes it's so weird it only passes if I do echo "$(dirname)" or echo "$(realpath)" I am not really sure why 😅
@lanyou0 I gave the entire context of the three files to ChatGPT and asked why is that error occurring when removing that line, and the answer is outstanding.
Question: The issue is that when removing the line echo "$(dirname)" from script.sh then I get an error, why?
The issue likely arises because the line `echo "$(dirname)"` is forcing a call to `dirname` when `script.sh` is sourced. This call causes the script to fail and may mask other issues that become apparent when this line is removed. Here's a step-by-step analysis of what might be happening: 1. **With the `echo "$(dirname)"` line present**: - When `script.sh` is sourced by `test.sh`, the command `dirname` is executed. - Since `dirname` expects an argument (a path), the call without an argument likely produces an error or empty output. - This error might cause the script to terminate prematurely or behave unexpectedly, but it does not cause the `source` command to fail. - As a result, the rest of `script.sh` is executed, and `external.sh` is sourced successfully. 2. **When the `echo "$(dirname)"` line is removed**: - The problematic `dirname` call is no longer executed, so no immediate error occurs from that line. - The script proceeds to the next line: `source "$(dirname "${BASH_SOURCE[0]}")"/external.sh`. - Here, `dirname "${BASH_SOURCE[0]}"` should give the directory containing the current script, but if `BASH_SOURCE[0]` is not set or not set correctly, it might lead to an invalid path being constructed. - If `dirname "${BASH_SOURCE[0]}"` returns an empty string or an incorrect directory, the `source` command will fail because it cannot find `external.sh`. ### Troubleshooting Steps 1. **Check the Output of `dirname "${BASH_SOURCE[0]}"`**: Add a debug statement before the `source` line to check what path is being constructed: ```bash # script.sh echo "Sourcing external.sh from: $(dirname "${BASH_SOURCE[0]}")/external.sh" source "$(dirname "${BASH_SOURCE[0]}")"/external.sh ``` 2. **Ensure `BASH_SOURCE` is Set Correctly**: Verify that `BASH_SOURCE` is being set correctly when `script.sh` is sourced by `test.sh`. It should contain the path to `script.sh`. 3. **Check for Other Errors**: Ensure there are no other hidden issues in `script.sh` or `external.sh` that might be causing the failure when the problematic line is removed. ### Example Debugging Update `script.sh` to include debug information: ```bash #!/bin/bash # script.sh # Add debug information echo "Current script directory: $(dirname "${BASH_SOURCE[0]}")" source "$(dirname "${BASH_SOURCE[0]}")"/external.sh function my_help() { echo "Usage: script.sh [options]" smth "BASH_SOURCE: ${BASH_SOURCE[0]}" exit 1 } ``` Run `test.sh` again and observe the output. This should give you more information about why the `source` command might be failing. If the issue persists, share the debug output, and we can further investigate the problem.
@lanyou0 the error seems to be on the redirection to the error output inside the smth()
function -> >&2
.
If you remove that redirection then it will work 🤔
function smth(){
# echo "$*" >&2
echo "$*"
}
```bash # (FD = File Descriptor) # Duplicate the current std-output (FD 1) and assigns it to FD 3. # This means that FD 3 now points to wherever the std-output was pointing. exec 3>&1 local test_execution_result test_execution_result=$( state::initialize_assertions_count runner::run_set_up # 2>&1: Redirects the std-error (FD 2) to the std-output (FD 1). # 1>&3: Redirects the std-output (FD 1) to FD 3, which, as set up earlier, # points to the original std-output. "$function_name" "$@" 2>&1 1>&3 # <---- HERE runner::run_tear_down runner::clear_mocks state::export_assertions_count ) # Closes FD 3, which was used temporarily to hold the original std-output. exec 3>&- # ... ```
The question now is, if (and how?) we want/can allow this feature of redirecting the output of a command to the standard error stream instead of the standard output with >&2
🤔 CC: @cmayo @antonio-gg-dev @khru
@lanyou0 can you try adding exec 2>&3
to your test_help()
? check this out: https://github.com/TypedDevs/bashunit/pull/274
```bash function test_help() { exec 2>&3 local result result="$(my_help)" assert_exit_code 1 } ```
Btw: I also experienced the problem that output on stderr
makes test fail.
The biggest DX issue with this IMO is, that we don't get a clear error message which shows why the test is failling (e.g. because of output to stderr on line xy)
Hey!
Thank you very much for your help and replies!
I tried these solutions to see if it was the error but echo "$*"
still failed if I did not have the echo "$(realpath)"
or echo "$(dirname)"
in script.sh.
I also see that you have created a pull request to redirect the file descriptor error, could you explain to me a bit more how it would help with the stderr?
@lanyou0 Here I wrote the reason: https://github.com/TypedDevs/bashunit/issues/272#issuecomment-2183967605 Click on The reason is coming from src/runner.sh:169
TL:DR: by redirecting the stderr to another FD (with
exec 2>&3 2>/dev/null
) so the stderr from your logic does not interfere with bashunit stderr FD
@lanyou0 good news! @cmayo found the fix for this issue: https://github.com/TypedDevs/bashunit/pull/275
Install the beta version (which contains main
branch) and try it out again 🙏
curl -s https://bashunit.typeddevs.com/install.sh | bash -s [dir] beta
(docs)
Hello, I am trying out your framework with some files I possess, but for some reason, every time I run my tests after sourcing my
script.sh
file, my tests fail. For context, myscript.sh
file is sourcing another file (outside of any function) and also exports some variables (outside of any function). I am wondering if this is a bug in the framework or if the framework does not support sourcing files that execute commands outside of functions for testing. Thank you.