Define a common mktemp for tests

GNU and BSD `mktemp` handle options differently, and it's a useful
utility for tests. As such, define a common `mktemp` function wrapper
for the test suite.

It might actually be nice to expand this for more flags and support it
globally, but that may result in confusion for any users of BSD mktemp
that expect to be running /bin/mktemp.
This commit is contained in:
Kevin Ballard 2014-10-27 20:48:39 -07:00
parent e13d423b68
commit 83df5ea660
3 changed files with 113 additions and 8 deletions

View file

@ -82,11 +82,10 @@ echo ()[1]
echo ()[d]
# Test tilde expansion
# On OS X, we must pass an argument to mktemp,
# and /tmp is symlinked to /private/tmp
# On OS X, /tmp is symlinked to /private/tmp
# $PWD is our best bet for resolving it
set -l saved $PWD
cd (mktemp -d /tmp/fish_tilde_XXXXXX)
cd (mktemp -d)
set tmpdir $PWD
cd $saved
mkdir $tmpdir/realhome

View file

@ -0,0 +1,101 @@
# GNU and BSD mktemp differ in their handling of arguments
# Let's expose a simplified common interface
function mktemp
# usage: mktemp [-d] [-t] [template]
#
# If the -d flag is given, create a directory.
#
# If the -t flag is given, treat the template as a filename relative
# to the temporary directory. The template may contain slashes but only
# the final path component is created by mktemp. The template must not be
# absolute
#
# If no template is given, assume tmp.XXXXXXXXXX and -t.
set -l opts
while set -q argv[1]
switch $argv[1]
case -d
set opts $opts d
case -t
set opts $opts t
case --
set -e argv[1]
break
case '-*'
echo "mktemp: unknown flag $argv[1]" >&2
_mktemp_help >&2
exit 2
case '*'
break
end
set -e argv[1]
end
set -l template
if set -q argv[1]
set template $argv[1]
else
set template 'tmp.XXXXXXXXXX'
set opts $opts t
end
if set -q argv[2]
echo 'mktemp: too many templates' >&2
_mktemp_help >&2
exit 1
end
# GNU sed treats the final occurrence of a sequence of X's as the template token.
# BSD sed only treats X's as the template token if they suffix the string.
# So let's outlaw them anywhere besides the end.
# Similarly GNU sed requires at least 3 X's, BSD sed requires none. Let's require 3.
begin
set -l IFS
printf '%s' "$template" | read -la chars
set -l found_x
for c in $chars
if test $c = X
set found_x $found_x X
else if set -q found_x[1]
echo 'mktemp: X\'s may only occur at the end of the template' >&2
_mktemp_help >&2
exit 1
end
end
if test (count $found_x) -lt 3
echo "mktemp: too few X's in template '$template'" >&2
_mktemp_usage >&2
exit 1
end
end
set -l args
if contains d $opts
set args $args -d
end
if contains t $opts
switch $template
case '/*'
echo "mktemp: invalid template '$template' with -t, template must not be absolute" >&2
_mktemp_help >&2
exit 1
end
switch "$TMPDIR"
case ''
set template /tmp/$template
case '*/'
set template $TMPDIR$template
case '*'
set template $TMPDIR/$template
end
end
set args $args $template
command mktemp $args
end
function _mktemp_help
echo 'usage: mktemp [-d] [-t] [template]'
echo 'note: mktemp is a test function, see tests/test_functions/mktemp.fish'
end

View file

@ -1,3 +1,4 @@
# vim: set ts=4 sw=4 et:
# Utilities for the test runners
if test "$argv[1]" = (status -f)
@ -38,8 +39,10 @@ if not set -q __fish_is_running_tests
rm -r $XDG_CONFIG_HOME; or die
end
mkdir -p $XDG_CONFIG_HOME/fish; or die
ln -s $PWD/test_functions $XDG_CONFIG_HOME/fish/functions; or die
set -l escaped_parent (dirname $PWD | sed -e 's/[\'\\\\]/\\\\&/g'); or die
printf 'set fish_function_path \'%s/share/functions\'\n' $escaped_parent > $XDG_CONFIG_HOME/fish/config.fish; or die
set -l escaped_config (printf '%s/fish' $XDG_CONFIG_HOME | sed -e 's/[\'\\\\]/\\\\&/g'); or die
printf 'set fish_function_path \'%s/functions\' \'%s/share/functions\'\n' $escaped_config $escaped_parent > $XDG_CONFIG_HOME/fish/config.fish; or die
set -xl __fish_is_running_tests $XDG_CONFIG_HOME
exec ../fish $script
die 'exec failed'
@ -51,10 +54,12 @@ else if test "$__fish_is_running_tests" != "$XDG_CONFIG_HOME"
else
# we're running tests with a temporary config directory
function test_util_on_exit --on-process-exit %self -V __fish_is_running_tests
# remove the temporary config directory
# unfortunately if this fails we can't alter the exit status of fish
if not rm -r "$__fish_is_running_tests"
echo "error: Couldn't remove temporary config directory '$__fish_is_running_tests'" >&2
if not set -q __fish_test_keep_tmp_config
# remove the temporary config directory
# unfortunately if this fails we can't alter the exit status of fish
if not rm -r "$__fish_is_running_tests"
echo "error: Couldn't remove temporary config directory '$__fish_is_running_tests'" >&2
end
end
end
# unset __fish_is_running_tests so any children that source