Skip to content

Instantly share code, notes, and snippets.

@usefulthink
Created March 13, 2012 11:31
Show Gist options
  • Save usefulthink/2028248 to your computer and use it in GitHub Desktop.
Save usefulthink/2028248 to your computer and use it in GitHub Desktop.
a micro bash-library for unit-testing RewriteRules
RewriteEngine On
RewriteBase /
# redirect anything from /common/* to /common/prefix/*, except of course
# /common/prefix/* itself (and except eventually existing files).
# ... dont rewrite if a file with that name exists
RewriteCond %{REQUEST_FILENAME} !-f
# ... dont rewrite URIs starting with /common/prefix/ (/foo/common/prefix
# and /common/prefix2 will be ignored)
RewriteCond %{REQUEST_URI} !^/common/prefix/
RewriteRule ^common/(.*)$ common/prefix/$1 [L,R=302,NC]
# forward anything that is not an actual file to index.php for processing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]

redirUnit - minimalistic unit-testing for rewrite-rules

write some tests:

# base-url to be used for all requests within this file
export BASE_URL="http://localhost"

section "this is a section-title..."
  # tests that the given path doesn't issue a Location-Header
  assertNoRedirect "/foo"

  # tests that the first path redirects to the second path
  assertNoRedirect "/foo/bar" "/foo/baz"

  # in case you want to skip some tests (maybe because you can't run them
  # for some reason). First parameter is the number of skipped tests,
  # second the message.
  skip 2 "just for testing..."

... and run them:

$ ./rewriteUnit <test-file ...>

You can also use parameters in the test-cases:

# in the testfile:
if [ "$SKIP_SOMETHING" ] ; then
    skip 1 "can't test something.."
else
    assert...
fi

and define them with

$ ./rewriteUnit <test-file> -D SKIP_SOMETHING=1
<?php var_dump($_SERVER);
#!/bin/bash
_tests=0
_passed=0
_skipped=0
_failed=0
# _getLocationFromUrl $url $pathOnly
_getLocationFromUrl() {
local location="$(curl -I "$1" 2> /dev/null \
| grep Location | sed -e 's,Location:\s*\(\S*\)\s*$,\1,')"
local redirPath="${location/$BASE_URL/}"
[[ $# -eq 1 ]] \
&& echo $location \
|| echo $redirPath
[[ -z "$location" ]] \
&& return 1 \
|| return 0
}
startFile() {
printf "\n\033[1;33m-------- file: %s\033[0m\n" "$@"
}
section() {
printf "\033[1;33m> %s\033[0m\n" "$@"
}
# skip $numTests $msg
skip() {
printf "\033[33m [SKIP]\033[0m %s (%d test(s))\n" "$2" "$1"
_tests=$(($_tests + $1))
_skipped=$(($_skipped + $1))
}
summary() {
summary=$(printf "%d tests - %d passed, %d skipped, %d failed" \
$_tests $_passed $_skipped $_failed)
if [ $_passed -eq $_tests ] ; then
printf "\n\033[7;32mResult: All tests passed (%s).\n\033[0m\n" "$summary"
return 0
elif [ $_failed -eq 0 ] ; then
printf "\n\033[7;33mResult: OK, but skipped Tests present (%s).\033[0m\n" "$summary"
return 1
else
printf "\n\033[37;41mResult: Failed (%s).\033[0m\n" "$summary"
return 2
fi
}
# assertLocalRedirect $path $expectedLocation
assertLocalRedirect() {
local location="$(curl -I "$BASE_URL/$1" 2> /dev/null \
| grep Location | sed -e 's,Location:\s*\(\S*\)\s*$,\1,')"
local redirPath="${location/$BASE_URL/}"
_tests=$(($_tests + 1))
if [ "$redirPath" == "$2" ] ; then
printf "\033[32m [PASS]\033[0m"
_passed=$(($_passed + 1 ))
else
printf "\033[31m [FAIL]\033[0m"
_failed=$(($_failed + 1))
fi
printf " redirect: \033[37m%s\033[0m -> \033[37m%s\033[0m\n" "$1" "$2"
}
# assertLocalRedirect $path
assertNoRedirect() {
local location=$(_getLocationFromUrl "$BASE_URL$1" true)
_tests=$(($_tests + 1))
if [ -z "$location" ] ; then
printf "\033[32m [PASS]\033[0m not redirected: \033[37m%s\033[0m\n" "$1"
_passed=$(($_passed + 1))
else
printf "\033[31m [FAIL]\033[0m"
printf " not redirected: \033[37m%s\033[0m (was redirected to: \033[37m%s\033[0m)\n" "$1" "$location"
_failed=$(($_failed + 1))
fi
}
# ----
# ---- MAIN
# ----
printHelp() {
cat <<- __EOT__
USAGE:
$(basename $0) [OPTIONS] <file ...>
OPTIONS:
-D KEY=VALUE export the given value into the environment of the tests
--help -h -? you're looking at it.
__EOT__
}
if [ $# -eq 0 ] ; then
printHelp && exit 0
fi
shortopts="h,?,D:"
longopts="help"
TMP=$(getopt -n "$(basename $0)" -l "$longopts" -o "$shortopts" -- "$@" )
if [ $? != 0 ] ; then print_help && exit 1 ; fi
eval set -- "$TMP"
while [ $# -gt 0 ] ; do
case $1 in
-D)
eval export "$2"
shift 2
;;
-h|-\?|--help)
print_help && exit 0
;;
--)
shift 1
while [ $# -gt 0 ] ; do
startFile "$1"
source $1
shift 1
done
;;
*)
echo "unknown parameter: $1"
print_help
exit 11
;;
esac
done
summary
exit $?
export BASE_URL="http://rewrite-test.mari.spot-media.net"
export DOCUMENT_ROOT=~/local/public_html/rewrite-test
section "test redirects for /common/prefix"
assertNoRedirect "/foo"
assertNoRedirect "/common/prefix/foo"
assertNoRedirect "/foo/common/prefix"
assertNoRedirect "/foo/common/something"
assertLocalRedirect "/common/redirected" "/common/prefix/redirected"
assertNoRedirect "/common/redirected"
section "test redirects for existing files"
if [ ! -d "$DOCUMENT_ROOT" ] ; then
skip 1 "not tested: existing files should not be redirected"
else
file="$DOCUMENT_ROOT/common/test-$(date +%s%N|md5sum|cut -c-10)"
mkdir -p "$(dirname $file)" && touch $file
assertNoRedirect "/common/$(basename $file)"
rm $file
fi
export BASE_URL="http://rewrite-test.mari.spot-media.net"
section "some other tests"
if [ "$DO_SKIP" ] ; then
skip 2 "just for testing..."
else
assertNoRedirect "/foo"
assertNoRedirect "/common/redirected"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment