sstephenson / bats

Bash Automated Testing System
MIT License
7.13k stars 517 forks source link

`run` cannot recognize alias #199

Open Aludirk opened 7 years ago

Aludirk commented 7 years ago

I have a function:

function error_msg_func()
{
  local filename="${1}"
  local lineno=${2}
  echo "error xxx (${filename}:${lineno})"
}

For convenient:

shopt -s expand_aliases
alias error_msg='error_msg_func "${BASH_SOURCE[0]}" ${LINENO}'

So I can easy to use:

error_msg

and no need to type "${BASH_SOURCE[0]}" and ${LINENO} every time

When I try to test it:

@test "error_msg" {
  run error_msg
  [ "${output}" = <expected result> ]
}

I got bats/libexec/bats-exec-test: line 58: error_msg: command not found

however, the following one is okay:

@test "error_msg_func" {
  run error_msg_func "${BASH_SOURCE[0]}" ${LINENO}
  [ "${output}" = <expected result> ]
}
suewonjp commented 7 years ago

If you use Bash 4, you can use builtin BASH_ALIASES (refer to man page for Bash) variable to emulate aliases;

Say that you want to use myAlias in test cases, then you can define a function as follows in your test helper script:

In test_helper.bash

myAlias() {
  $( echo ${BASH_ALIASES[myAlias]} $@ )
}

In your test case:

load test_helper

@test "test" {
    run myAlias hello world
    [ $status -eq 0 ]
}

But if run command natively supports aliases, I think it would be much more great and convenient;

dimo414 commented 7 years ago

Why not just declare a function instead of an alias? They're more reliable and don't require escaping strings:

error_msg() {
  error_msg_func "${BASH_SOURCE[0]}" "${LINENO}"
}
suewonjp commented 7 years ago

Of course, we all use functions. We implement all functionalities within functions, but

This is good. But except one or two params, users may rarely use the rest of the params, which may happen in real world. Also, some params may be just for internal usage, which users don't have to know in the first place.

Also, making the users type extra characters (like underscores) for your function names might be annoying from the user's perspective.

One workaround is, we use aliases like so:

alias al='_core_func foo var baz hello world true false'

So users just type less characters and they don't have to focus on extra details until they seriously need to access those extra details.

Of course, you may use simpler function names and wrapper functions with less params to wrap your core functions, which may look a lot user-friendly.

But still, name collisions may happen when you stick to functions as your outermost interface.

Of course, you need to provide users a simple mechanism to replace the default alias names with whatever names suit them best.

Please, see my file search tool lf.sh for more detailed usage

Or refer to z which is a more renowned project which I referenced to build lf.sh