Commit graph

440 commits

Author SHA1 Message Date
Fabian Homborg
aa17ed51ce tests/checks/complete: Do $PWD stuff in the tempdir
This broke the tests on my machine, and doing

```fish
cd $dir
cd -
```

seems wrong in any case.
2021-08-30 17:07:11 +02:00
Fabian Homborg
d62e22dcc0 Correct a realpath test
This used the *logical* $PWD, but realpath would operate on the
physical $PWD if given ".", even with -s. This makes this test fail if the $PWD is
logically different from physical.
2021-08-29 23:10:50 +02:00
Johannes Altmanninger
77c434bc42 Extract setup and teardown for tmux tests
This was long overdue since the setup logic is much more complex than
the actual tests.

tmux-prompt.fish had extra logic to protect against XDG_CONFIG_HOME
with leading double double-dot.  I believe this is no longer necessary
with the new test driver.

We still use our own temp dir because we want to be able to run this
independently of the test driver, This can be useful for debugging
tests.  For example we can insert a "$tmux attach" command in a test,
and then run

	build/fish -C 'source tests/test_functions/isolated-tmux.fish' tests/checks/tmux-bind.fish

This allows to inspect the state of the test and debug interactively.
Attaching to the terminal doesn't work when running inside littlecheck
because littlecheck consumes our output and doesn't give us a terminal.
(Maybe there's an easy way to fix that?)
2021-08-29 20:22:16 +02:00
Johannes Altmanninger
bd79e753ff Fix detection of zombies in test
Due to the second column the old glob no longer worked.
2021-08-29 20:22:16 +02:00
Mahmoud Al-Qudsi
069d396ebc Merge branch 'ctest' 2021-08-29 13:03:16 -05:00
Mahmoud Al-Qudsi
9a071090dc Allow tests/checks/basic.fish to run without test driver
On request of a team member, this patches `basic.fish` to no longer
depend on being invoked by the test driver and started up in a $PWD that
points to a clean temporary directory.
2021-08-29 12:53:37 -05:00
Mahmoud Al-Qudsi
2157d91a5c Re-add explicit littlecheck HOME/XDG_CONFIG_HOME overrides on request
This was requested by a team member who would like for some tests to
remain invokable (in thier own $HOME) directly via littlecheck without
relying on the test driver to prep the environment.

A comment explaining the rationale is also added so this doesn't get
passed down as folklore "you need to include this for tests to run" even
though no one understands why.
2021-08-29 12:38:28 -05:00
Mahmoud Al-Qudsi
e96b6e157c Remove TMPDIR dependency from tests/
Tests are now executed in a test-specific temporary directory, so test
output on failure should be reproducible/reusable as-is without needing
to have TMPDIR defined (as it only exists by default under macOS).
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
ef00344c0e Fix tmux tests error on macOS w/ long TMPDIR 2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
efda4f5c39 Make zombie test smarter
Instead of trying to assert that there are no zombies when the test
starts (which often fails) and to prevent conflating existing or
irrelevant zombies with the ones we are interested in checking for,
have `ps` also emit the parent process id and filter its output to
include only children of the current fish instance.
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
9796b95f48 Eliminate shared temporary directory for tests
Aside from the fact that the shared state could cause problems, tests
were randomly assuming it would be created where that wasn't the case.
In particular, `redirect.fish` and `basic.fish` were failing on only
macOS because `../test/temp` didn't exist yet - it would be created by
other tests later.
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
c35113aef1 Remove now-extraneous re-init of XDG dirs in tests
test_driver.sh is guaranteed to take care of them.
2021-08-29 08:56:12 +02:00
Mahmoud Al-Qudsi
77b332221a Fix complete.fish test
It depends on `mktemp -d TAG` returning a relative path, which isn't guaranteed to be the case (and
isn't the case when run by our test driver).
2021-08-29 08:56:12 +02:00
Fabian Homborg
4c3cb119fc Actually return when reading file failed
Fixes #8258.
2021-08-29 08:36:54 +02:00
Mahmoud Al-Qudsi
498e5fa9b0 [tests] Set permissions on tmux socket after creation 2021-08-28 22:55:53 +02:00
ridiculousfish
2ca66cff53 Disable job control inside command substitutions
This disables job control inside command substitutions. Prior to this
change, a cmdsub might get its own process group. This caused it to fail
to cancel loops properly. For example:

    while true ; echo (sleep 5) ; end

could not be control-C cancelled, because the signal would go to sleep,
and so the loop would continue on. The simplest way to fix this is to
match other shells and not use job control in cmdsubs.

Related is #1362
2021-08-18 22:20:03 +08:00
Fabian Homborg
6c5c8e03c5 Move the numeric locale tests to a different file
This lets us check for locales once, and to have littlecheck mark the
test as skipped.
2021-08-17 15:36:07 +02:00
David Adam
a8fddf3d9b add tests for zero-index expressions
See 5326462116 / #8213.
2021-08-17 12:41:03 +08:00
Mahmoud Al-Qudsi
0a4f80ec41 Add more tests for literal zero indexes 2021-08-15 13:48:41 -05:00
Fabian Homborg
c4593828f4
commandline: Add --is-valid option (#8142)
* commandline: Add --is-valid option to query whether it's syntactically complete

This means querying when the commandline is in a state that it could
be executed. Because our `execute` bind function also inserts a
newline if it isn't.

One case that's not handled right now: `execute` also expands
abbreviations, those can technically make the commandline invalid
again.

Unfortunately we have no real way to *check* without doing the
replacement.

Also since abbreviations are only available in command position when
you _execute_ them the commandline will most likely be valid.

This is enough to make transient prompts work:

```fish
function reset-transient --on-event fish_postexec
    set -g TRANSIENT 0
end

function maybe_execute
    if commandline --is-valid
        set -g TRANSIENT 1
        commandline -f repaint
    else
        set -g TRANSIENT 0
    end
    commandline -f execute
end

bind \r maybe_execute
```

and then in `fish_prompt` react to $TRANSIENT being set to 1.
2021-08-14 11:29:22 +02:00
Fabian Homborg
eee38836cf set -q: Return 255 if no variable name was passed
Previously this strictly returned the number of unset variables. So if
no variable was given, it would return *true*, which is highly
suspect.
2021-08-14 10:55:21 +02:00
Fabian Homborg
b5e5732be1 Point wildcard error at a more specific help section
"Expansion" covers *all* the expansions, that's a bit of a handful.

Directly point people towards globbing.
2021-08-11 18:40:37 +02:00
Fabian Homborg
6c1ec98e92 prompt_pwd: full-dirs set to 0 means not even last component is safe
Alternative is to print an error.
2021-08-09 17:42:00 +02:00
Fabian Homborg
af2952dd2f Allow passing directories to prompt_pwd
This allows us to test it without cd-ing about the place.
2021-08-09 17:42:00 +02:00
Fabian Homborg
2087a3ca63 Let visible length work with CR and LF
Because we are, ultimately, interested in how many cells a string
occupies, we *have* to handle carriage return (`\r`) and line
feed (`\n`).

A carriage return sets the current tally to 0, and only the longest
tally is kept. The idea here is that the last position is the same as
the last position of the longest string. So:

abcdef\r123

ends up looking like

123def

which is the same width as abcdef, 6.

A line feed meanwhile means we flush the current tally and start a new
one. Every line is printed separately, even if it's given as one.

That's because, well, counting the width over multiple lines
doesn't *help*.

As a sidenote: This is necessarily imperfect, because, while we may
know the width of the terminal ($COLUMNS), we don't know the current
cursor position. So we can only give the width, and the user can then
figure something out on their own.

But for the common case of figuring out how wide the prompt is, this
should do.
2021-08-04 21:09:47 +02:00
Fabian Homborg
0059192f61 Allow erasing vars via function-scope
This triggered an assert because the remove code had no idea how to
find the function scope.

Oops!
2021-08-04 17:55:41 +02:00
Fabian Homborg
733114fefb
Add set --function (#8145)
* Add `set --function`

This makes the function's scope available, even inside of blocks. Outside of blocks it's the toplevel local scope.

This removes the need to declare variables locally before use, and will probably end up being the main way variables get set.

E.g.:

```fish
set -l thing
if condition
    set thing one
else
    set thing two
end
```

could be written as

```fish
if condition
    set -f thing one
else
    set -f thing two
end
```

Note: Many scripts shipped with fish use workarounds like `and`/`or`
instead of `if`, so it isn't easy to find good examples.

Also, if there isn't an else-branch in that above, just with

```fish
if condition
    set -f thing one
end
```

that means something different from setting it before! Now, if
`condition` isn't true, it would use a global (or universal) variable of
te same name!

Some more interesting parts:

Because it *is* a local scope, setting a variable `-f` and
`-l` in the toplevel of a function ends up the same:

```fish
function foo2
    set -l foo bar
    set -f foo baz # modifies the *same* variable!
end
```

but setting it locally inside a block creates a new local variable
that shadows the function-scoped variable:

```fish
function foo3
    set -f foo bar
    begin
        set -l foo banana
        # $foo is banana
    end
    # $foo is bar again
end
```

This is how local variables already work. "Local" is actually "block-scoped".

Also `set --show` will only show the closest local scope, so it won't
show a shadowed function-level variable. Again, this is how local
variables already work, and could be done as a separate change.

As a fun tidbit, functions with --no-scope-shadowing can now use this to set variables in the calling function. That's probably okay given that it's already an escape hatch (but to be clear: if it turns out to problematic I reserve the right to remove it).

Fixes #565
2021-08-01 20:08:12 +02:00
Johannes Altmanninger
66709571ed fish_indent: handle tokens with trailing escaped newlines
Fixes #8197
2021-08-01 18:59:45 +02:00
Johannes Altmanninger
3a375c2399 reader: fix regressions when moving between lines
Fixes some regressions from 35ca42413 ("Simplify some parse_util functions").
The tmux tests are not beautiful but I find them easy to write.
Probably a pexpect test would also be enough here?
2021-08-01 17:50:44 +02:00
Fabian Homborg
dd3cdbcfc9 Fix crash if $PWD is used as for-loop variable
for PWD in foo; true; end

prints:

>..src/parse_execution.cpp:461: end_execution_reason_t parse_execution_context_t::run_for_statement(const ast::for_header_t&, const ast::job_list_t&): Assertion `retval == ENV_OK' failed.

because this used the wrong way to see if something is read-only.
2021-07-30 15:33:04 +02:00
Fabian Homborg
09b8471f5c Test numeric locale
This allows us to test that `test` takes numbers with decimal point even in comma-using locales,
to stop those pesky americans from breaking everything again.

(and yes, we use french to keep myself honest)
2021-07-29 17:20:20 +02:00
Fabian Homborg
b3cdf4afe1 Hardcode $PWD as read-only for set --show
Through a mechanism I don't entirely understand, $PWD is sometimes
writable (so that `cd` can change it) and sometimes not.

In this case we ended up with it writable, which is wrong.

See #8179.
2021-07-28 22:13:22 +02:00
Fabian Homborg
3db78232c6 Show if a var is read-only with set --show
Fixes #8179.
2021-07-28 21:13:03 +02:00
Fabian Homborg
29e9f4838a Run parse_util_detect_errors on -c commands
This didn't do all the syntax checks, so something like

    fish -c 'echo foo; and $status'

complained of a missing command `0` (i.e. $status), and

    fish -c 'echo foo | exec grep'

hit an assert!

So we do what read_ni does, parse each command into an ast, run
parse_util_detect_errors on it if it worked and then eval the ast.

It is possible to do this neater by modifying parser::eval, but I
can't find where.
2021-07-27 18:37:20 +02:00
Fabian Homborg
08209b3d9a Forbid $status as a command
This is slightly unclean. Even tho it would otherwise be syntactically
valid, using $status as a command is very very very likely to be an
error, like

    if not $status

We have reports of this surprisingly regularly, including #2773.

Because $status can only ever be a value from 0 to 255, it is also
very unlikely to be an actual command, and that command is very
unlikely to do what you want.

So we simply point the user towards the "conditions" help section,
that should explain things.
2021-07-27 18:37:20 +02:00
Fabian Homborg
d32e1c12be tinyexpr: Check for nan in ncr
Turns out this takes ages.

Fixes #8170
2021-07-26 18:40:50 +02:00
Johannes Altmanninger
a2b30053dc Teach fish_indent about our feature flags
So it can handle syntax changes that call for different formatting.
2021-07-23 22:58:51 +02:00
Johannes Altmanninger
cc32b4f2a7 Make '&' only background if followed by a separating character
This is opt-in through a new feature flag "ampersand-nobg-in-token".

When this flag and "qmark-noglob" are enabled, this command no longer
needs quoting:

	curl https://example.com/thing?foo=bar&duran=duran

Compared to the previous approach e1570a4 ("Let '&' only separate as
the first char of a word"), this has some advantages:

1. "&&" and "&>" are no longer affected. They are still special, even
   if used between tokens without spaces, like "echo bar&>foo".
   Maybe this is not really *better*, but it avoids risking to annoy
   users by breaking the old variant.

2. "&" is still special if at the end of a token, like in "sleep 1&".

Word movement is not affected by the semantics change, so Alt-F and
friends still stop at every "&".
2021-07-23 22:58:51 +02:00
Fabian Homborg
859edc9c2c Implicitly use $PWD in $CDPATH in completions and highlighting
We already do for the actual cd-ing itself.

Missed in #4484.

Fixes #8161.
2021-07-23 17:22:06 +02:00
Fabian Homborg
3359e5d2e9
Let "return" exit a script (#8148)
Currently, if a "return" is given outside of a function, we'd just
throw an error.

That always struck me as a bit weird, given that scripts can also
return a value.

So simply let "return" outside also exit the script, kinda like "exit"
does.

However, unlike "exit" it doesn't quit an interactive shell - it seems
weird to have "return" do that as well. It sets $status, so it can be
used to quickly set that, in case you want to test something.
2021-07-21 22:33:39 +02:00
Fabian Homborg
e9a793532e Stop cd "" from crashing
Fixes #8147.
2021-07-17 19:03:15 +02:00
Fabian Homborg
f3f6e4a982 string: Add "--groups-only" to match
This adds a simple way of picking bits from a string that might be a
bit nicer than having to resort to a full `replace`.

Fixes #6056
2021-07-16 20:27:54 +02:00
Fabian Homborg
e013422143 Deduplicate $fish_user_paths automatically
In the variable handler, we just go through the entire thing and keep
every element once.

If there's a duplicate, we set it again, which calls the handler
again.

This takes a bit of time, to be paid on each startup. On my system,
with 100 already deduplicated elements, that's about 4ms (compared to
~17ms for adding them to $PATH).

It's also semantically more complicated - now this variable
specifically is deduplicated? Do we just want "unique" variables that
can't have duplicates?

However: This entirely removes the pathological case of appending to
$fish_user_paths in config.fish (which should be an FAQ entry!), and the implementation is quite simple.
2021-07-14 16:37:30 +02:00
Johannes Altmanninger
405ef31f72 Increase tmux-prompt test timeout in CI
This failed on Ubuntu and Mac.
2021-07-14 08:46:03 +02:00
Johannes Altmanninger
0ab6735450 Support $(cmd) command substitution as alternative to (cmd)
For consistency with "$(cmd)" and with other shells.
2021-07-13 21:33:42 +02:00
Johannes Altmanninger
ec3d3a481b Support "$(cmd)" command substitution without line splitting
This adds a hack to the parser. Given a command

	echo "x$()y z"

we virtually insert double quotes before and after the command
substitution, so the command internally looks like

	echo "x"$()"y z"

This hack allows to reuse the existing logic for handling (recursive)
command substitutions.

This makes the quoting syntax more complex; external highlighters
should consider adding this if possible.

The upside (more Bash compatibility) seems worth it.

Closes #159
2021-07-13 21:33:42 +02:00
Johannes Altmanninger
e50805646e completions/git: define function before use 2021-07-12 23:42:01 +02:00
Johannes Altmanninger
e3d8b315ed Avoid global and user git config leaking into git tests 2021-07-12 23:42:01 +02:00
Tair Sabyrgaliyev
8f7ea1f5b6 fix 'socket file name too long' error
In some setups (eg. macports) $tmpdir can expand to more than
100 symbols and tests fail with 'socket file name too long'
errors.

Using relative path to socket file fixes the issue.
2021-07-11 09:28:51 +02:00
Fabian Homborg
0e1f5108ae
string: Allow collect --allow-empty to avoid empty ellision (#8054)
* string: Allow `collect --no-empty` to avoid empty ellision

Currently we still have that issue where

    test -n (thing | string collect)

can return true if `thing` doesn't print anything, because the
collected argument will still be removed.

So, what we do is allow `--no-empty` to be used, in which case we
print one empty argument.

This means

    test -n (thing | string collect -n)

can now be safely used.

"no-empty" isn't the best name for this flag, but string's design
really incentivizes reusing names, and it's not *terrible*.

* Switch to `--allow-empty`

`--no-empty` does the exact opposite for `string split` and split0.

Since `-a`/`--allow-empty` already exists, use it.
2021-07-09 21:20:58 +02:00