Skip to content
Permalink
d1a1f28786
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 303 lines (249 sloc) 13.1 KB
#!/usr/bin/env sh
set +o verbose
# Usage:
# ------
# This script runs both our test-suites, and, if they've been downloaded, checks conformance with
# the Paws rulebooks.
#
# Of note, our test suite is spread across three toolsets:
#
# - `mocha`, to run most of the unit-tests and the the JavaScript API integration tests,
# - `bats`, to run the executable's unit-tests as well as the CLI integration tests,
# - and finally `paws.js check` itself (via `taper`) to check Rulebook conformance.
#
# npm test
#
# npm test -- --grep 'Parser' # Run a specific unit-test suite
# INTEGRATION=no npm test # Run the unit-tests *only* (not the integration tests)
#
# BATS=no npm test # Disable execution of any shell-tests
# RULEBOOK=no npm test # Ignore the Rulebook, even if present
# LETTERS=yes npm test # Execute the Letters, as well as the rest of the Rulebook
#
# WATCH=yes npm test # Watch filesystem for changes, and automatically re-run
# DEBUGGER=yes npm test # Expose the Blink debugger-tools on localhost:8080
# COVERAGE=yes npm test # Generate a coverage report with Istanbul
# RESPECT_TRACING=no npm test # Disable debugging and tracing during the tests
#
# Given `$COVERAGE`, a coverage-report will be constructed as the test suites execute. By default,
# this results in an HTML page (`Docs/Coverage/index.html`), and a textual summary along with the
# test-output.
#
# If the tests pass as invoked, then a `.tests-succeeded` file is created to cache this status, with
# SHA-sums of the source-code and test files; this cache allows automatic pre-commit runs to be
# omitted when tests have been already run. (NOTE: This intentionally ignores `--grep` and other
# flags; meaning that it's possible to commit broken code by excluding broken tests!)
puts() { printf %s\\n "$@" ;}
pute() { printf %s\\n "~~ $*" >&2 ;}
argq() { [ $# -gt 0 ] && printf "'%s' " "$@" ;}
source_dir="$npm_package_config_dirs_source"
bin_dir="$npm_package_config_dirs_bin"
unit_dir="$npm_package_config_dirs_test"
integration_dir="$npm_package_config_dirs_integration"
rulebook_dir="$npm_package_config_dirs_rulebook"
coverage_dir="$npm_package_config_dirs_coverage"
mocha_ui="$npm_package_config_mocha_ui"
mocha_reporter="$npm_package_config_mocha_reporter"
cache_file="$unit_dir/.tests-succeeded"
# ‘cache results’
cr=yes
export NODE_ENV='test'
# FIXME: This should support *excluded* modules with a minus, as per `node-debug`:
# https://github.com/visionmedia/debug
if echo "$DEBUG" | grep -qE '(^|,\s*)(\*|Paws.js(:(scripts|\*))?)($|,)'; then # 1. $DEBUG_SCRIPTS
pute "Script debugging enabled (in: `basename $0`)."
DEBUG_SCRIPTS=yes
VERBOSE="${VERBOSE:-7}"
fi
# Configuration-variable setup
# ----------------------------
# The continuous-integration system on Travis is special-cased. See the header of `travis.sh` for
# more details about how all of this interacts.
if [ -n "${CI##[NFnf]*}" ]; then cr=no # 2. $CI
[ -n "$DEBUG_SCRIPTS" ] && pute "Enabling CI mode."
#mocha_reporter="..." # This is manually manipulated in `travis.sh`
BATS_FLAGS="$BATS_FLAGS --tap"
# In CI-mode, the runners *default* to being exclusive of eachother, except when generating final
# coverage after a successful build.
if [ -n "${COVERAGE##[NFnf]*}" ]; then
UNIT="${UNIT:-yes}"
BATS="${BATS:-yes}"
RULEBOOK="${RULEBOOK:-yes}"
LETTERS="${LETTERS:-yes}"
elif [ -n "${RULEBOOK##[NFnf]*}" ]; then
UNIT="${UNIT:-no}"
BATS="${BATS:-no}"
LETTERS="${LETTERS:-yes}"
elif [ -n "${BATS##[NFnf]*}" ]; then
UNIT="${UNIT:-no}"
RULEBOOK="${RULEBOOK:-no}"
else
UNIT="${UNIT:-yes}"
BATS="${BATS:-no}"
RULEBOOK="${RULEBOOK:-no}"
fi
elif [ -n "${PRE_COMMIT##[NFnf]*}" ]; then cr=no # 3. $PRE_COMMIT
[ -n "$DEBUG_SCRIPTS" ] && pute "Enabling pre-commit mode."
mocha_reporter=dot # Be quiet,
ISTANBUL_REPORTER='text-summary'
RESPECT_TRACING=no # if the user has a ‘loud’ environment configured, ignore it,
RULEBOOK=no # don't guarantee that the Rulebook passes on every commit,
UNIT=yes BATS=yes INTEGRATION=yes COVERAGE=yes # ... but otherwise, run all of the suites.
else
[ -n "$DEBUG_SCRIPTS" ] && pute "Running in interactive-invocation mode."
# When raw arguments are passed (presumably, for `mocha`) or the Node debugger is enabled, we
# default to not running the other suites.
if [ -n "$*" ] || [ -n "${DEBUGGER##[NFnf]*}" ]; then cr=no
[ -z "$BATS" ] && BATS=no # 4. $BATS
[ -z "$RULEBOOK" ] && RULEBOOK=no # 5. $RULEBOOK
fi
# If you're running the (slow) BATS integration-suite, *and* running the rest of the unit tests,
# there's no reason whatsoever not to also run the mocha integration tests.
[ -z "${BATS##[YTyt]*}" ] && INTEGRATION=yes # 6. $INTEGRATION
if [ -n "${DEBUGGER##[NFnf]*}" ]; then cr=no # 7. $DEBUGGER
debugging=yes
# FIXME: It's actually specifiaclly Node v6.3.0 that first introduced native `--inspect`
# support; I need to do a true semver comparison for this — this will fail between
# v6.0.0 and v6.3.0.
[ "${npm_config_node_version%%.*}" -lt 6 ] && \
debug_with_module=yes
WATCH='no'
if [ -n "$debug_with_module" ]; then
if [ ! -x "./node_modules/.bin/node-debug" ]; then
pute 'You must `npm install node-inspector` to use the $DEBUGGER flag on Node versions'
pute ' prior to v6.3.0.'
exit 127
fi
[ -z "${DEBUG_MODULES##[NFnf]*}" ] && \
hidden='--hidden node_modules/'
invocation_guard="./node_modules/.bin/node-debug $hidden --cli --config \
'./Scripts/node-inspectorrc.json'"
else
invocation_guard="node --inspect --debug-brk"
fi
fi
if [ -n "${WATCH##[NFnf]*}" ]; then # 8. $WATCH
[ ! -x "./node_modules/.bin/chokidar" ] &&
pute 'You must `npm install chokidar-cli` to use the $WATCH flag!' && exit 127
fi
fi
# Aliases so I can stop tying `YTyt` :P
[ -z "${INTEGRATION##[YTyt]*}" ] && integration=yes
[ -n "${COVERAGE##[NFnf]*}" ] && coverage=yes
# Verbosity and printing configuration
# ------------------------------------
if [ -n "${RESPECT_TRACING##[YTyt]*}" ]; then # 9. $RESPECT_TRACING
[ -n "$DEBUG_SCRIPTS" ] && pute "Disrespecting tracing flags"
VERBOSE=4 # 'warning' and worse
unset TRACE_REACTOR
fi
# 10. $print_commands
[ -z "${SILENT##[NFnf]*}${QUIET##[NFnf]*}" ] && [ "${VERBOSE:-4}" -gt 6 ] && print_commands=yes
[ -n "$DEBUG_SCRIPTS" ] && puts \
"Pre-commit mode: ${PRE_COMMIT:--}" \
"CI (Travis) mode: ${CI:--}" \
"Caching results: ${cr:--}" \
"" \
"Tracing reactor: ${TRACE_REACTOR:+Yes!}" \
"Watching filesystem: ${WATCH:--}" \
"Running debugger: ${DEBUGGER:--}" \
"Using node-inspector: ${debug_with_module:-No!}" \
"Generating coverage: ${COVERAGE:--}" \
"Debugging modules: ${DEBUG_MODULES:--}" \
"" \
"Verbosity: '$VERBOSE'" \
"Printing commands: ${print_commands:--}" \
"" \
"Tests dir: '$unit_dir'" \
"Integration dir: '$integration_dir'" \
"Rulebook dir: '$rulebook_dir'" \
"Coverage dir: '$coverage_dir'" \
"" \
"Running units: ${UNIT:--}" \
"Running shell tests: ${BATS:--}" \
"Running integration: ${INTEGRATION:--}" \
"Checking rulebook: ${RULEBOOK:--}" \
"Checking letters: ${LETTERS:--}" \
"" >&2
[ -n "$DEBUG_SCRIPTS" ] && [ "${VERBOSE:-4}" -gt 8 ] && \
pute "Environment variables:" && env >&2
# Helper-function setup
# ---------------------
go () { [ -n "$print_commands" ] && puts '`` '"$*" >&2 ; "$@" || exit $? ;}
mochaify() {
[ -z "${UNIT##[YTyt]*}" ] && go $invocation_guard \
"./node_modules/.bin/${invocation_guard:+_}${coverage:+_}mocha" \
${debugging:+ --no-timeouts } \
${coverage:+ --require './Library/register-coffee-coverage.js' } \
--require mocha-clean/brief \
--compilers coffee:coffee-script/register \
--reporter "$mocha_reporter" --ui "$mocha_ui" \
"$@" ;}
batsify() {
if [ -z "${BATS##[YTyt]*}" ] && command -v bats >/dev/null; then
go bats --pretty $BATS_FLAGS "$@" ;fi ;}
ruleify() {
book="$1"; shift
if [ -d "$PWD/$rulebook_dir/$book/" ]; then
go $invocation_guard ./node_modules/.bin/taper \
--runner "$PWD/Executables/paws.js" --runner-param='check' \
"$PWD/$rulebook_dir/$book"/* \
$TAPER_FLAGS -- $CHECK_FLAGS "$@" ;fi ;}
cache() {
shasum "$source_dir"/* "$bin_dir"/* "$unit_dir"/* "$integration_dir"/* 2>/dev/null
}
gen_cache() {
if [ "$cr" != 'no' ]; then
[ -n "$DEBUG_SCRIPTS" ] && pute "Generating cache of successful test-status"
cache >"$cache_file"
true ;fi ;}
check_cache() {
if [ -n "$DEBUG_SCRIPTS" ]; then
pute "Checking test-status cache"
[ -f "$cache_file" ] && shasum -c "$cache_file"
else
[ -f "$cache_file" ] && shasum -c "$cache_file" >/dev/null 2>&1 ;fi ;}
# Pre-execution
# -------------
if [ -n "${PRE_COMMIT##[NFnf]*}" ] && check_cache; then
pute 'Pre-commit: Using cached test exit-status from recent `npm test`!'
exit 0
fi
if [ -n "${WATCH##[NFnf]*}" ]; then
[ "${VERBOSE:-4}" -gt 7 ] && chokidar_verbosity='--verbose'
unset WATCH COVERAGE DEBUGGER
export UNIT BATS INTEGRATION RULEBOOK LETTERS VERBOSE TRACE_REACTOR
go exec chokidar \
"${chokidar_verbosity:---silent}" \
--initial --ignore '**/.*' \
"$source_dir" "$bin_dir" "$unit_dir" \
${integration:+"$integration_dir"} ${RULEBOOK:+"$rulebook_dir"} \
$CHOKIDAR_FLAGS -c "$0 $(argq "$@")"
fi
# Execution of tests
# ------------------ # i) Mocha,
mochaify "$unit_dir"/*.tests.coffee ${integration:+"$integration_dir/"*.tests.coffee} "$@"
# ii) Istanbul,
[ -n "$coverage" ] && istanbul report --config='Scripts/istanbul.config.js' $COVERAGE_REPORTER
batsify "$unit_dir"/*.tests.bats ${integration:+"$integration_dir/"*.tests.bats}
if ! command -v bats >/dev/null; then
[ -n "$DEBUG_SCRIPTS" ] && pute '`bats` not installed.'
puts 'Install `bats` to run the executable'\''s tests and CLI integration tests:'
puts ' <https://github.com/sstephenson/bats>'
# If explicitly requested, then the command missing is a fatal error.
[ -n "${BATS##[NFnf]*}" ] && exit 10
fi
if [ -z "${RULEBOOK##[YTyt]*}" ]; then
ruleify "The Ladder" # iv) Rulebooks,
ruleify "The Gauntlet"
[ -n "${LETTERS##[NFnf]*}" ] && \
ruleify "The Letters" --expose-specification
if [ ! -d "$PWD/$rulebook_dir" ]; then
[ -n "$DEBUG_SCRIPTS" ] && pute "Rulebook directory not found."
puts 'Clone the rulebook from this URL to `./'$rulebook_dir'` to check Rulebook compliance:'
puts ' <https://github.com/Paws/Rulebook.git>'
# If explicitly requested, then the Rulebook missing is a fatal error.
[ -n "${RULEBOOK##[NFnf]*}" ] && exit 11
fi
fi
gen_cache # v) cache!