From 739196e8245c3d712f6585589c209fa46e9b14a6 Mon Sep 17 00:00:00 2001 From: albfan Date: Tue, 30 Aug 2016 14:51:29 +0200 Subject: [PATCH] Add continuous integration --- .gitmodules | 3 + .travis.yml | 10 +- Makefile.am | 4 + README.md | 2 +- autogen.sh | 4 + bash-ini-parser | 6 +- build-aux/tap-driver.sh | 651 +++++++++++++++++++++++ configure.ac | 23 + t/.simplecov | 1 + t/Makefile | 52 -- t/Makefile.am | 4 + t/setup.sh | 17 + t/sharness | 1 + t/sharness/.travis.yml | 16 - t/sharness/API.md | 302 ----------- t/sharness/CHANGELOG.md | 116 ----- t/sharness/COPYING | 339 ------------ t/sharness/Makefile | 36 -- t/sharness/README.git | 709 ------------------------- t/sharness/README.md | 164 ------ t/sharness/aggregate-results.sh | 57 --- t/sharness/sharness.sh | 741 --------------------------- t/sharness/test/.gitignore | 3 - t/sharness/test/Makefile | 60 --- t/sharness/test/aggregate-results.sh | 1 - t/sharness/test/sharness.sh | 1 - t/sharness/test/sharness.t | 302 ----------- t/sharness/test/simple.t | 32 -- t/t0001-parse.sh | 17 +- t/t0002-invalid.sh | 14 +- t/t0003-sections.sh | 17 +- t/t0004-comments.sh | 12 +- 32 files changed, 743 insertions(+), 2974 deletions(-) create mode 100644 .gitmodules create mode 100644 Makefile.am create mode 100755 autogen.sh mode change 100644 => 100755 bash-ini-parser create mode 100755 build-aux/tap-driver.sh create mode 100644 configure.ac create mode 100644 t/.simplecov delete mode 100644 t/Makefile create mode 100644 t/Makefile.am create mode 100755 t/setup.sh create mode 160000 t/sharness delete mode 100644 t/sharness/.travis.yml delete mode 100644 t/sharness/API.md delete mode 100644 t/sharness/CHANGELOG.md delete mode 100644 t/sharness/COPYING delete mode 100644 t/sharness/Makefile delete mode 100644 t/sharness/README.git delete mode 100644 t/sharness/README.md delete mode 100755 t/sharness/aggregate-results.sh delete mode 100644 t/sharness/sharness.sh delete mode 100644 t/sharness/test/.gitignore delete mode 100644 t/sharness/test/Makefile delete mode 120000 t/sharness/test/aggregate-results.sh delete mode 120000 t/sharness/test/sharness.sh delete mode 100755 t/sharness/test/sharness.t delete mode 100755 t/sharness/test/simple.t diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e50475b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "t/sharness"] + path = t/sharness + url = https://github.com/mlafeldt/sharness.git diff --git a/.travis.yml b/.travis.yml index 2d1ec4c..e5277c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,12 +5,12 @@ compiler: before_install: -script: cd t && make SHELL=/bin/bash +script: cd t && make -## whitelist -branches: - only: - - master +script: + - ./autogen.sh + - cd t + - make check notifications: email: diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..adbf1d7 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +bin_SCRIPTS = bash-ini-parser +CLEAN_FILES = $(bin_SCRIPTS) + +SUBDIRS = t diff --git a/README.md b/README.md index 7b29f08..e6c5a24 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## bash-ini-parser +## bash-ini-parser [![Build Status](https://travis-ci.org/albfan/bash-ini-parser.svg?branch=master)](https://travis-ci.org/albfan/bash-ini-parser) A ini file parser for bash relying only on builtins diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..c0f7e54 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +autoreconf -ivf +./configure diff --git a/bash-ini-parser b/bash-ini-parser old mode 100644 new mode 100755 index c42c432..23384e0 --- a/bash-ini-parser +++ b/bash-ini-parser @@ -203,5 +203,9 @@ function cfg_update { eval "function $item" } - +#Test harness +if [ $# != 0 ] +then + $@ +fi # vim: filetype=sh diff --git a/build-aux/tap-driver.sh b/build-aux/tap-driver.sh new file mode 100755 index 0000000..82efa96 --- /dev/null +++ b/build-aux/tap-driver.sh @@ -0,0 +1,651 @@ +#! /bin/sh +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +scriptversion=2013-12-23.17; # UTC + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +me=tap-driver.sh + +fatal () +{ + echo "$me: fatal: $*" >&2 + exit 1 +} + +usage_error () +{ + echo "$me: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat < + # + trap : 1 3 2 13 15 + if test $merge -gt 0; then + exec 2>&1 + else + exec 2>&3 + fi + "$@" + echo $? + ) | LC_ALL=C ${AM_TAP_AWK-awk} \ + -v me="$me" \ + -v test_script_name="$test_name" \ + -v log_file="$log_file" \ + -v trs_file="$trs_file" \ + -v expect_failure="$expect_failure" \ + -v merge="$merge" \ + -v ignore_exit="$ignore_exit" \ + -v comments="$comments" \ + -v diag_string="$diag_string" \ +' +# TODO: the usages of "cat >&3" below could be optimized when using +# GNU awk, and/on on systems that supports /dev/fd/. + +# Implementation note: in what follows, `result_obj` will be an +# associative array that (partly) simulates a TAP result object +# from the `TAP::Parser` perl module. + +## ----------- ## +## FUNCTIONS ## +## ----------- ## + +function fatal(msg) +{ + print me ": " msg | "cat >&2" + exit 1 +} + +function abort(where) +{ + fatal("internal error " where) +} + +# Convert a boolean to a "yes"/"no" string. +function yn(bool) +{ + return bool ? "yes" : "no"; +} + +function add_test_result(result) +{ + if (!test_results_index) + test_results_index = 0 + test_results_list[test_results_index] = result + test_results_index += 1 + test_results_seen[result] = 1; +} + +# Whether the test script should be re-run by "make recheck". +function must_recheck() +{ + for (k in test_results_seen) + if (k != "XFAIL" && k != "PASS" && k != "SKIP") + return 1 + return 0 +} + +# Whether the content of the log file associated to this test should +# be copied into the "global" test-suite.log. +function copy_in_global_log() +{ + for (k in test_results_seen) + if (k != "PASS") + return 1 + return 0 +} + +function get_global_test_result() +{ + if ("ERROR" in test_results_seen) + return "ERROR" + if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) + return "FAIL" + all_skipped = 1 + for (k in test_results_seen) + if (k != "SKIP") + all_skipped = 0 + if (all_skipped) + return "SKIP" + return "PASS"; +} + +function stringify_result_obj(result_obj) +{ + if (result_obj["is_unplanned"] || result_obj["number"] != testno) + return "ERROR" + + if (plan_seen == LATE_PLAN) + return "ERROR" + + if (result_obj["directive"] == "TODO") + return result_obj["is_ok"] ? "XPASS" : "XFAIL" + + if (result_obj["directive"] == "SKIP") + return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; + + if (length(result_obj["directive"])) + abort("in function stringify_result_obj()") + + return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL +} + +function decorate_result(result) +{ + color_name = color_for_result[result] + if (color_name) + return color_map[color_name] "" result "" color_map["std"] + # If we are not using colorized output, or if we do not know how + # to colorize the given result, we should return it unchanged. + return result +} + +function report(result, details) +{ + if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) + { + msg = ": " test_script_name + add_test_result(result) + } + else if (result == "#") + { + msg = " " test_script_name ":" + } + else + { + abort("in function report()") + } + if (length(details)) + msg = msg " " details + # Output on console might be colorized. + print decorate_result(result) msg + # Log the result in the log file too, to help debugging (this is + # especially true when said result is a TAP error or "Bail out!"). + print result msg | "cat >&3"; +} + +function testsuite_error(error_message) +{ + report("ERROR", "- " error_message) +} + +function handle_tap_result() +{ + details = result_obj["number"]; + if (length(result_obj["description"])) + details = details " " result_obj["description"] + + if (plan_seen == LATE_PLAN) + { + details = details " # AFTER LATE PLAN"; + } + else if (result_obj["is_unplanned"]) + { + details = details " # UNPLANNED"; + } + else if (result_obj["number"] != testno) + { + details = sprintf("%s # OUT-OF-ORDER (expecting %d)", + details, testno); + } + else if (result_obj["directive"]) + { + details = details " # " result_obj["directive"]; + if (length(result_obj["explanation"])) + details = details " " result_obj["explanation"] + } + + report(stringify_result_obj(result_obj), details) +} + +# `skip_reason` should be empty whenever planned > 0. +function handle_tap_plan(planned, skip_reason) +{ + planned += 0 # Avoid getting confused if, say, `planned` is "00" + if (length(skip_reason) && planned > 0) + abort("in function handle_tap_plan()") + if (plan_seen) + { + # Error, only one plan per stream is acceptable. + testsuite_error("multiple test plans") + return; + } + planned_tests = planned + # The TAP plan can come before or after *all* the TAP results; we speak + # respectively of an "early" or a "late" plan. If we see the plan line + # after at least one TAP result has been seen, assume we have a late + # plan; in this case, any further test result seen after the plan will + # be flagged as an error. + plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) + # If testno > 0, we have an error ("too many tests run") that will be + # automatically dealt with later, so do not worry about it here. If + # $plan_seen is true, we have an error due to a repeated plan, and that + # has already been dealt with above. Otherwise, we have a valid "plan + # with SKIP" specification, and should report it as a particular kind + # of SKIP result. + if (planned == 0 && testno == 0) + { + if (length(skip_reason)) + skip_reason = "- " skip_reason; + report("SKIP", skip_reason); + } +} + +function extract_tap_comment(line) +{ + if (index(line, diag_string) == 1) + { + # Strip leading `diag_string` from `line`. + line = substr(line, length(diag_string) + 1) + # And strip any leading and trailing whitespace left. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + # Return what is left (if any). + return line; + } + return ""; +} + +# When this function is called, we know that line is a TAP result line, +# so that it matches the (perl) RE "^(not )?ok\b". +function setup_result_obj(line) +{ + # Get the result, and remove it from the line. + result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) + sub("^(not )?ok[ \t]*", "", line) + + # If the result has an explicit number, get it and strip it; otherwise, + # automatically assing the next progresive number to it. + if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) + { + match(line, "^[0-9]+") + # The final `+ 0` is to normalize numbers with leading zeros. + result_obj["number"] = substr(line, 1, RLENGTH) + 0 + line = substr(line, RLENGTH + 1) + } + else + { + result_obj["number"] = testno + } + + if (plan_seen == LATE_PLAN) + # No further test results are acceptable after a "late" TAP plan + # has been seen. + result_obj["is_unplanned"] = 1 + else if (plan_seen && testno > planned_tests) + result_obj["is_unplanned"] = 1 + else + result_obj["is_unplanned"] = 0 + + # Strip trailing and leading whitespace. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + + # This will have to be corrected if we have a "TODO"/"SKIP" directive. + result_obj["description"] = line + result_obj["directive"] = "" + result_obj["explanation"] = "" + + if (index(line, "#") == 0) + return # No possible directive, nothing more to do. + + # Directives are case-insensitive. + rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" + + # See whether we have the directive, and if yes, where. + pos = match(line, rx "$") + if (!pos) + pos = match(line, rx "[^a-zA-Z0-9_]") + + # If there was no TAP directive, we have nothing more to do. + if (!pos) + return + + # Let`s now see if the TAP directive has been escaped. For example: + # escaped: ok \# SKIP + # not escaped: ok \\# SKIP + # escaped: ok \\\\\# SKIP + # not escaped: ok \ # SKIP + if (substr(line, pos, 1) == "#") + { + bslash_count = 0 + for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) + bslash_count += 1 + if (bslash_count % 2) + return # Directive was escaped. + } + + # Strip the directive and its explanation (if any) from the test + # description. + result_obj["description"] = substr(line, 1, pos - 1) + # Now remove the test description from the line, that has been dealt + # with already. + line = substr(line, pos) + # Strip the directive, and save its value (normalized to upper case). + sub("^[ \t]*#[ \t]*", "", line) + result_obj["directive"] = toupper(substr(line, 1, 4)) + line = substr(line, 5) + # Now get the explanation for the directive (if any), with leading + # and trailing whitespace removed. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + result_obj["explanation"] = line +} + +function get_test_exit_message(status) +{ + if (status == 0) + return "" + if (status !~ /^[1-9][0-9]*$/) + abort("getting exit status") + if (status < 127) + exit_details = "" + else if (status == 127) + exit_details = " (command not found?)" + else if (status >= 128 && status <= 255) + exit_details = sprintf(" (terminated by signal %d?)", status - 128) + else if (status > 256 && status <= 384) + # We used to report an "abnormal termination" here, but some Korn + # shells, when a child process die due to signal number n, can leave + # in $? an exit status of 256+n instead of the more standard 128+n. + # Apparently, both behaviours are allowed by POSIX (2008), so be + # prepared to handle them both. See also Austing Group report ID + # 0000051 + exit_details = sprintf(" (terminated by signal %d?)", status - 256) + else + # Never seen in practice. + exit_details = " (abnormal termination)" + return sprintf("exited with status %d%s", status, exit_details) +} + +function write_test_results() +{ + print ":global-test-result: " get_global_test_result() > trs_file + print ":recheck: " yn(must_recheck()) > trs_file + print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file + for (i = 0; i < test_results_index; i += 1) + print ":test-result: " test_results_list[i] > trs_file + close(trs_file); +} + +BEGIN { + +## ------- ## +## SETUP ## +## ------- ## + +'"$init_colors"' + +# Properly initialized once the TAP plan is seen. +planned_tests = 0 + +COOKED_PASS = expect_failure ? "XPASS": "PASS"; +COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; + +# Enumeration-like constants to remember which kind of plan (if any) +# has been seen. It is important that NO_PLAN evaluates "false" as +# a boolean. +NO_PLAN = 0 +EARLY_PLAN = 1 +LATE_PLAN = 2 + +testno = 0 # Number of test results seen so far. +bailed_out = 0 # Whether a "Bail out!" directive has been seen. + +# Whether the TAP plan has been seen or not, and if yes, which kind +# it is ("early" is seen before any test result, "late" otherwise). +plan_seen = NO_PLAN + +## --------- ## +## PARSING ## +## --------- ## + +is_first_read = 1 + +while (1) + { + # Involutions required so that we are able to read the exit status + # from the last input line. + st = getline + if (st < 0) # I/O error. + fatal("I/O error while reading from input stream") + else if (st == 0) # End-of-input + { + if (is_first_read) + abort("in input loop: only one input line") + break + } + if (is_first_read) + { + is_first_read = 0 + nextline = $0 + continue + } + else + { + curline = nextline + nextline = $0 + $0 = curline + } + # Copy any input line verbatim into the log file. + print | "cat >&3" + # Parsing of TAP input should stop after a "Bail out!" directive. + if (bailed_out) + continue + + # TAP test result. + if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) + { + testno += 1 + setup_result_obj($0) + handle_tap_result() + } + # TAP plan (normal or "SKIP" without explanation). + else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) + { + # The next two lines will put the number of planned tests in $0. + sub("^1\\.\\.", "") + sub("[^0-9]*$", "") + handle_tap_plan($0, "") + continue + } + # TAP "SKIP" plan, with an explanation. + else if ($0 ~ /^1\.\.0+[ \t]*#/) + { + # The next lines will put the skip explanation in $0, stripping + # any leading and trailing whitespace. This is a little more + # tricky in truth, since we want to also strip a potential leading + # "SKIP" string from the message. + sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") + sub("[ \t]*$", ""); + handle_tap_plan(0, $0) + } + # "Bail out!" magic. + # Older versions of prove and TAP::Harness (e.g., 3.17) did not + # recognize a "Bail out!" directive when preceded by leading + # whitespace, but more modern versions (e.g., 3.23) do. So we + # emulate the latter, "more modern" behaviour. + else if ($0 ~ /^[ \t]*Bail out!/) + { + bailed_out = 1 + # Get the bailout message (if any), with leading and trailing + # whitespace stripped. The message remains stored in `$0`. + sub("^[ \t]*Bail out![ \t]*", ""); + sub("[ \t]*$", ""); + # Format the error message for the + bailout_message = "Bail out!" + if (length($0)) + bailout_message = bailout_message " " $0 + testsuite_error(bailout_message) + } + # Maybe we have too look for dianogtic comments too. + else if (comments != 0) + { + comment = extract_tap_comment($0); + if (length(comment)) + report("#", comment); + } + } + +## -------- ## +## FINISH ## +## -------- ## + +# A "Bail out!" directive should cause us to ignore any following TAP +# error, as well as a non-zero exit status from the TAP producer. +if (!bailed_out) + { + if (!plan_seen) + { + testsuite_error("missing test plan") + } + else if (planned_tests != testno) + { + bad_amount = testno > planned_tests ? "many" : "few" + testsuite_error(sprintf("too %s tests run (expected %d, got %d)", + bad_amount, planned_tests, testno)) + } + if (!ignore_exit) + { + # Fetch exit status from the last line. + exit_message = get_test_exit_message(nextline) + if (exit_message) + testsuite_error(exit_message) + } + } + +write_test_results() + +exit 0 + +} # End of "BEGIN" block. +' + +# TODO: document that we consume the file descriptor 3 :-( +} 3>"$log_file" + +test $? -eq 0 || fatal "I/O or internal error" + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f92b9d4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,23 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.68]) +AC_INIT([bash-ini-parser], [1.0], [albertofanjul@gmail.com]) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([foreign 1.11]) + +# Checks for programs. +AC_PROG_INSTALL + +# Checks for libraries. + +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. + +AC_CONFIG_FILES([Makefile + t/Makefile]) +AC_REQUIRE_AUX_FILE([tap-driver.sh]) +AC_OUTPUT diff --git a/t/.simplecov b/t/.simplecov new file mode 100644 index 0000000..5622ac8 --- /dev/null +++ b/t/.simplecov @@ -0,0 +1 @@ +Bashcov.root_directory(File.expand_path('../../', Dir.getwd)) diff --git a/t/Makefile b/t/Makefile deleted file mode 100644 index b715cd0..0000000 --- a/t/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -SHELL_PATH ?= $(SHELL) -PROVE ?= prove -DEFAULT_TEST_TARGET ?= test -TAP_OUT ?= tapout - -SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) - -T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) - -all: $(DEFAULT_TEST_TARGET) - -test: pre-clean - @$(MAKE) aggregate-results-and-cleanup - -prove: pre-clean - @echo '*** prove ***'; prove --exec '$(SHELL_PATH_SQ)' $(PROVE_OPTS) $(T) :: $(TEST_OPTS) - @$(MAKE) clean-except-prove-cache - -tap: pre-clean clean-tap - mkdir $(TAP_OUT) - @$(MAKE) aggregate-results-and-cleanup - -clean-tap: - @$(RM) -r $(TAP_OUT) - -aggregate-results: - @for f in test-results/t*-*.counts; do \ - echo "$$f"; \ - done | '$(SHELL_PATH_SQ)' ./sharness/aggregate-results.sh - -pre-clean: - @$(RM) -r test-results - -clean-except-prove-cache: - @$(RM) -r 'trash directory'.* test-results - -clean: clean-except-prove-cache - @$(RM) .prove - -aggregate-results-and-cleanup: $(T) - @$(MAKE) aggregate-results - @$(MAKE) clean - -$(T): -ifeq ($(DEFAULT_TEST_TARGET),tap) - @echo '*** $@ ***'; '$(SHELL_PATH_SQ)' $@ > $(TAP_OUT)/$@ -else - @echo '*** $@ ***'; '$(SHELL_PATH_SQ)' $@ -endif - -.PHONY: all test prove tap aggregate-results $(T) -.PHONY: pre-clean clean-except-prove-cache clean clean-tap aggregate-results-and-cleanup diff --git a/t/Makefile.am b/t/Makefile.am new file mode 100644 index 0000000..830a7be --- /dev/null +++ b/t/Makefile.am @@ -0,0 +1,4 @@ +TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \ + $(top_srcdir)/build-aux/tap-driver.sh +TESTS = t0001-parse.sh t0002-invalid.sh t0003-sections.sh t0004-comments.sh +EXTRA_DIST = $(TESTS) diff --git a/t/setup.sh b/t/setup.sh new file mode 100755 index 0000000..ccec05f --- /dev/null +++ b/t/setup.sh @@ -0,0 +1,17 @@ +. sharness/sharness.sh + +SHARNESS_TEST_EXTENSION="bash" + +export GEM_PATH=$GEM_PATH:/home/alberto/.gem/ruby/2.2.0 + +if test "$COVERAGE" = "yes" +then + COMMAND="$COV_PROGRAM ../../bash-ini-parser" +else + . ../../bash-ini-parser + COMMAND="" +fi + +export COMMAND + +DIR_TEST=$SHARNESS_TEST_DIRECTORY/${0%%-*} diff --git a/t/sharness b/t/sharness new file mode 160000 index 0000000..2298d6a --- /dev/null +++ b/t/sharness @@ -0,0 +1 @@ +Subproject commit 2298d6a491f43da26a89175173b6b56edd4313dd diff --git a/t/sharness/.travis.yml b/t/sharness/.travis.yml deleted file mode 100644 index 750a4f8..0000000 --- a/t/sharness/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: erlang # no shell language support; use least-loaded worker(s) - -env: - - TEST_OPTS=-v - - DEFAULT_TEST_TARGET=prove - -install: - - sudo make install prefix=/usr/local - -script: - - make test - - sudo make -C /usr/local/share/doc/sharness/examples - -branches: - only: - - master diff --git a/t/sharness/API.md b/t/sharness/API.md deleted file mode 100644 index 6395eed..0000000 --- a/t/sharness/API.md +++ /dev/null @@ -1,302 +0,0 @@ -# Sharness API - -### SHARNESS_VERSION - - Public: Current version of Sharness. - -### SHARNESS_TEST_EXTENSION - - Public: The file extension for tests. By default, it is set to "t". - -### test_set_prereq() - - Public: Define that a test prerequisite is available. - - The prerequisite can later be checked explicitly using test_have_prereq or - implicitly by specifying the prerequisite name in calls to test_expect_success - or test_expect_failure. - - $1 - Name of prerequiste (a simple word, in all capital letters by convention) - - Examples - - # Set PYTHON prerequisite if interpreter is available. - command -v python >/dev/null && test_set_prereq PYTHON - - # Set prerequisite depending on some variable. - test -z "$NO_GETTEXT" && test_set_prereq GETTEXT - - Returns nothing. - -### test_have_prereq() - - Public: Check if one or more test prerequisites are defined. - - The prerequisites must have previously been set with test_set_prereq. - The most common use of this is to skip all the tests if some essential - prerequisite is missing. - - $1 - Comma-separated list of test prerequisites. - - Examples - - # Skip all remaining tests if prerequisite is not set. - if ! test_have_prereq PERL; then - skip_all='skipping perl interface tests, perl not available' - test_done - fi - - Returns 0 if all prerequisites are defined or 1 otherwise. - -### test_debug() - - Public: Execute commands in debug mode. - - Takes a single argument and evaluates it only when the test script is started - with --debug. This is primarily meant for use during the development of test - scripts. - - $1 - Commands to be executed. - - Examples - - test_debug "cat some_log_file" - - Returns the exit code of the last command executed in debug mode or 0 - otherwise. - -### test_expect_success() - - Public: Run test commands and expect them to succeed. - - When the test passed, an "ok" message is printed and the number of successful - tests is incremented. When it failed, a "not ok" message is printed and the - number of failed tests is incremented. - - With --immediate, exit test immediately upon the first failed test. - - Usually takes two arguments: - $1 - Test description - $2 - Commands to be executed. - - With three arguments, the first will be taken to be a prerequisite: - $1 - Comma-separated list of test prerequisites. The test will be skipped if - not all of the given prerequisites are set. To negate a prerequisite, - put a "!" in front of it. - $2 - Test description - $3 - Commands to be executed. - - Examples - - test_expect_success \ - 'git-write-tree should be able to write an empty tree.' \ - 'tree=$(git-write-tree)' - - # Test depending on one prerequisite. - test_expect_success TTY 'git --paginate rev-list uses a pager' \ - ' ... ' - - # Multiple prerequisites are separated by a comma. - test_expect_success PERL,PYTHON 'yo dawg' \ - ' test $(perl -E 'print eval "1 +" . qx[python -c "print 2"]') == "4" ' - - Returns nothing. - -### test_expect_failure() - - Public: Run test commands and expect them to fail. Used to demonstrate a known - breakage. - - This is NOT the opposite of test_expect_success, but rather used to mark a - test that demonstrates a known breakage. - - When the test passed, an "ok" message is printed and the number of fixed tests - is incremented. When it failed, a "not ok" message is printed and the number - of tests still broken is incremented. - - Failures from these tests won't cause --immediate to stop. - - Usually takes two arguments: - $1 - Test description - $2 - Commands to be executed. - - With three arguments, the first will be taken to be a prerequisite: - $1 - Comma-separated list of test prerequisites. The test will be skipped if - not all of the given prerequisites are set. To negate a prerequisite, - put a "!" in front of it. - $2 - Test description - $3 - Commands to be executed. - - Returns nothing. - -### test_must_fail() - - Public: Run command and ensure that it fails in a controlled way. - - Use it instead of "! ". For example, when dies due to a - segfault, test_must_fail diagnoses it as an error, while "! " would - mistakenly be treated as just another expected failure. - - This is one of the prefix functions to be used inside test_expect_success or - test_expect_failure. - - $1.. - Command to be executed. - - Examples - - test_expect_success 'complain and die' ' - do something && - do something else && - test_must_fail git checkout ../outerspace - ' - - Returns 1 if the command succeeded (exit code 0). - Returns 1 if the command died by signal (exit codes 130-192) - Returns 1 if the command could not be found (exit code 127). - Returns 0 otherwise. - -### test_might_fail() - - Public: Run command and ensure that it succeeds or fails in a controlled way. - - Similar to test_must_fail, but tolerates success too. Use it instead of - " || :" to catch failures caused by a segfault, for instance. - - This is one of the prefix functions to be used inside test_expect_success or - test_expect_failure. - - $1.. - Command to be executed. - - Examples - - test_expect_success 'some command works without configuration' ' - test_might_fail git config --unset all.configuration && - do something - ' - - Returns 1 if the command died by signal (exit codes 130-192) - Returns 1 if the command could not be found (exit code 127). - Returns 0 otherwise. - -### test_expect_code() - - Public: Run command and ensure it exits with a given exit code. - - This is one of the prefix functions to be used inside test_expect_success or - test_expect_failure. - - $1 - Expected exit code. - $2.. - Command to be executed. - - Examples - - test_expect_success 'Merge with d/f conflicts' ' - test_expect_code 1 git merge "merge msg" B master - ' - - Returns 0 if the expected exit code is returned or 1 otherwise. - -### test_cmp() - - Public: Compare two files to see if expected output matches actual output. - - The TEST_CMP variable defines the command used for the comparision; it - defaults to "diff -u". Only when the test script was started with --verbose, - will the command's output, the diff, be printed to the standard output. - - This is one of the prefix functions to be used inside test_expect_success or - test_expect_failure. - - $1 - Path to file with expected output. - $2 - Path to file with actual output. - - Examples - - test_expect_success 'foo works' ' - echo expected >expected && - foo >actual && - test_cmp expected actual - ' - - Returns the exit code of the command set by TEST_CMP. - -### test_when_finished() - - Public: Schedule cleanup commands to be run unconditionally at the end of a - test. - - If some cleanup command fails, the test will not pass. With --immediate, no - cleanup is done to help diagnose what went wrong. - - This is one of the prefix functions to be used inside test_expect_success or - test_expect_failure. - - $1.. - Commands to prepend to the list of cleanup commands. - - Examples - - test_expect_success 'test core.capslock' ' - git config core.capslock true && - test_when_finished "git config --unset core.capslock" && - do_something - ' - - Returns the exit code of the last cleanup command executed. - -### test_done() - - Public: Summarize test results and exit with an appropriate error code. - - Must be called at the end of each test script. - - Can also be used to stop tests early and skip all remaining tests. For this, - set skip_all to a string explaining why the tests were skipped before calling - test_done. - - Examples - - # Each test script must call test_done at the end. - test_done - - # Skip all remaining tests if prerequisite is not set. - if ! test_have_prereq PERL; then - skip_all='skipping perl interface tests, perl not available' - test_done - fi - - Returns 0 if all tests passed or 1 if there was a failure. - -### cleanup() - - Public: Schedule cleanup commands to be run unconditionally when all tests - have run. - - This can be used to clean up things like test databases. It is not needed to - clean up temporary files, as test_done already does that. - - Examples: - - cleanup mysql -e "DROP DATABASE mytest" - - Returns the exit code of the last cleanup command executed. - -### SHARNESS_TEST_DIRECTORY - - Public: Root directory containing tests. Tests can override this variable, - e.g. for testing Sharness itself. - -### SHARNESS_BUILD_DIRECTORY - - Public: Build directory that will be added to PATH. By default, it is set to - the parent directory of SHARNESS_TEST_DIRECTORY. - -### SHARNESS_TEST_FILE - - Public: Path to test script currently executed. - -### SHARNESS_TRASH_DIRECTORY - - Public: Empty trash directory, the test area, provided for each test. The HOME - variable is set to that directory too. - -Generated by tomdoc.sh version 0.1.4 diff --git a/t/sharness/CHANGELOG.md b/t/sharness/CHANGELOG.md deleted file mode 100644 index ba8f02b..0000000 --- a/t/sharness/CHANGELOG.md +++ /dev/null @@ -1,116 +0,0 @@ -v0.3.0 (2013-04-03) -------------------- - -This release is all about bringing upstream fixes and improvements from Git to -Sharness ([GH-7]). - -List of merged upstream changes: - -* Make test number come first in `not ok $count - $message`. -* Paint known breakages in yellow. -* Paint unexpectedly fixed known breakages in bold red. -* Paint skipped tests in blue. -* Change info messages from yellow/brown to cyan. -* Fix `say_color()` to not interpret `\a\b\c` in the message. -* Add check for invalid use of `skip_all` facility. -* Rename `$satisfied` to `$satisfied_prereq`. -* Allow negation of prerequisites with "!". -* Retain cache file `test/.prove` across prove runs. -* Replace `basic.t` with `sharness.t` which is an adapted version of - `t0000-basic.sh` from upstream. -* Update `README.git` with upstream changes. - -Other changes: - -* Add [git-integration] to the list of projects using Sharness. Also pay tribute - to Git's test suite. -* Let Travis only test the master branch (and pull requests). - -[GH-7]: https://github.com/mlafeldt/sharness/pull/7 -[git-integration]: https://github.com/johnkeeping/git-integration - -v0.2.5 (2013-03-29) -------------------- - -* Allow to install Sharness via `make install` and to uninstall it via - `make uninstall`. See brand-new installation instructions in README. ([GH-5]) -* Allow users to override the test extension via `SHARNESS_TEST_EXTENSION` if - they wish to. ([GH-6]) -* Don't set a variable and export it at the same time. ([GH-6]) -* Remove `TEST_INSTALLED` -- use `SHARNESS_BUILD_DIRECTORY` instead. -* Add vi modeline to `sharness.sh`. -* Add `AGGREGATE_SCRIPT` variable to `test/Makefile`. -* Remove superfluous `SHARNESS_TEST_DIRECTORY` assignments from `test/basic.t`. -* Add [timedb] to the list of projects using Sharness. -* Add Sharness alternatives to README. -* Rename HISTORY.md to CHANGELOG.md. - -[GH-5]: https://github.com/mlafeldt/sharness/pull/5 -[GH-6]: https://github.com/mlafeldt/sharness/pull/6 -[timedb]: http://git.cryptoism.org/cgit.cgi/timedb.git - -v0.2.4 (2012-07-13) -------------------- - -* Add `simple.t` to tests and README. -* Provide `SHARNESS_TEST_FILE` which is the path to the test script currently - being executed. -* Add [dabba] to the list of projects using Sharness. - -[dabba]: https://github.com/eroullit/dabba - -v0.2.3 (2012-06-20) -------------------- - -* Make `.t` the new test file extension, which is the default extension used by - `prove(1)`. (You can still use the `t????-*` scheme, but you need to rename - the `.sh` ending of all tests.) -* Rename, export, and document public variables `SHARNESS_TEST_DIRECTORY`, - `SHARNESS_BUILD_DIRECTORY`, and `SHARNESS_TRASH_DIRECTORY`. -* TomDoc `SHARNESS_TEST_EXTENSION`. - -v0.2.2 (2012-04-27) -------------------- - -* Document all public API functions using [TomDoc] and let [tomdoc.sh] generate - documentation in markdown format from it, see `API.md`. -* Rename `test_skip` to `test_skip_` as it is internal. -* Clean up `test/Makefile`. -* Sync Git README with upstream. - -[TomDoc]: http://tomdoc.org/ -[tomdoc.sh]: https://github.com/mlafeldt/tomdoc.sh - -v0.2.1 (2012-03-01) -------------------- - -* Fix: Redirect stdin of tests (by @peff). -* Unify coding style across all shell scripts. -* Remove superfluous functions `sane_unset` and `test_declared_prereq`. -* Get rid of variables `DIFF` and `TEST_CMP_USE_COPIED_CONTEXT`. -* Remove dysfunctional smoke testing targets from `test/Makefile`. -* Add Travis CI config. -* Add top-level Makefile to say `make test`. -* Add GPL header to all files from Git. - -v0.2.0 (2011-12-13) -------------------- - -* Rename `test-lib.sh` to `sharness.sh`. -* Strip more Git-specific functionality. -* Add variable `SHARNESS_VERSION`. -* Move self-tests to `test` folder; keep essential files in root. -* Update README. -* Add this history file. - -v0.1.1 (2011-11-02) -------------------- - -* Merge changes to test harness library from Git v1.7.8-rc0 - -v0.1.0 (2011-05-02) -------------------- - -* First version based on test harness library from Git v1.7.5 -* Remove Git-specific functions, variables, prerequisites, make targets, etc. -* Remove `GIT_` prefix from global variables. diff --git a/t/sharness/COPYING b/t/sharness/COPYING deleted file mode 100644 index d159169..0000000 --- a/t/sharness/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/t/sharness/Makefile b/t/sharness/Makefile deleted file mode 100644 index 255e055..0000000 --- a/t/sharness/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -prefix = $(HOME) - -INSTALL_DIR = $(prefix)/share/sharness -DOC_DIR = $(prefix)/share/doc/sharness -EXAMPLE_DIR = $(DOC_DIR)/examples - -INSTALL_FILES = aggregate-results.sh sharness.sh -DOC_FILES = API.md CHANGELOG.md COPYING README.git README.md -EXAMPLE_FILES = test/Makefile test/simple.t - -INSTALL = install -RM = rm -f -SED = sed -TOMDOCSH = tomdoc.sh - -all: - -install: all - $(INSTALL) -d -m 755 $(INSTALL_DIR) $(DOC_DIR) $(EXAMPLE_DIR) - $(INSTALL) -m 644 $(INSTALL_FILES) $(INSTALL_DIR) - $(INSTALL) -m 644 $(DOC_FILES) $(DOC_DIR) - $(SED) -e "s!aggregate-results.sh!$(INSTALL_DIR)/aggregate-results.sh!" test/Makefile > $(EXAMPLE_DIR)/Makefile - $(SED) -e "s!. ./sharness.sh!. $(INSTALL_DIR)/sharness.sh!" test/simple.t > $(EXAMPLE_DIR)/simple.t - -uninstall: - $(RM) -r $(INSTALL_DIR) $(DOC_DIR) $(EXAMPLE_DIR) - -doc: all - { printf "# Sharness API\n\n"; \ - $(TOMDOCSH) -m -a Public sharness.sh; \ - printf "Generated by "; $(TOMDOCSH) --version; } >API.md - -test: all - $(MAKE) -C test - -.PHONY: all install uninstall doc test diff --git a/t/sharness/README.git b/t/sharness/README.git deleted file mode 100644 index 6c30759..0000000 --- a/t/sharness/README.git +++ /dev/null @@ -1,709 +0,0 @@ -Core GIT Tests -============== - -This directory holds many test scripts for core GIT tools. The -first part of this short document describes how to run the tests -and read their output. - -When fixing the tools or adding enhancements, you are strongly -encouraged to add tests in this directory to cover what you are -trying to fix or enhance. The later part of this short document -describes how your test scripts should be organized. - - -Running Tests -------------- - -The easiest way to run tests is to say "make". This runs all -the tests. - - *** t0000-basic.sh *** - ok 1 - .git/objects should be empty after git init in an empty repo. - ok 2 - .git/objects should have 3 subdirectories. - ok 3 - success is reported like this - ... - ok 43 - very long name in the index handled sanely - # fixed 1 known breakage(s) - # still have 1 known breakage(s) - # passed all remaining 42 test(s) - 1..43 - *** t0001-init.sh *** - ok 1 - plain - ok 2 - plain with GIT_WORK_TREE - ok 3 - plain bare - -Since the tests all output TAP (see http://testanything.org) they can -be run with any TAP harness. Here's an example of parallel testing -powered by a recent version of prove(1): - - $ prove --timer --jobs 15 ./t[0-9]*.sh - [19:17:33] ./t0005-signals.sh ................................... ok 36 ms - [19:17:33] ./t0022-crlf-rename.sh ............................... ok 69 ms - [19:17:33] ./t0024-crlf-archive.sh .............................. ok 154 ms - [19:17:33] ./t0004-unwritable.sh ................................ ok 289 ms - [19:17:33] ./t0002-gitfile.sh ................................... ok 480 ms - ===( 102;0 25/? 6/? 5/? 16/? 1/? 4/? 2/? 1/? 3/? 1... )=== - -prove and other harnesses come with a lot of useful options. The ---state option in particular is very useful: - - # Repeat until no more failures - $ prove -j 15 --state=failed,save ./t[0-9]*.sh - -You can give DEFAULT_TEST_TARGET=prove on the make command (or define it -in config.mak) to cause "make test" to run tests under prove. -GIT_PROVE_OPTS can be used to pass additional options, e.g. - - $ make DEFAULT_TEST_TARGET=prove GIT_PROVE_OPTS='--timer --jobs 16' test - -You can also run each test individually from command line, like this: - - $ sh ./t3010-ls-files-killed-modified.sh - ok 1 - git update-index --add to add various paths. - ok 2 - git ls-files -k to show killed files. - ok 3 - validate git ls-files -k output. - ok 4 - git ls-files -m to show modified files. - ok 5 - validate git ls-files -m output. - # passed all 5 test(s) - 1..5 - -You can pass --verbose (or -v), --debug (or -d), and --immediate -(or -i) command line argument to the test, or by setting GIT_TEST_OPTS -appropriately before running "make". - ---verbose:: - This makes the test more verbose. Specifically, the - command being run and their output if any are also - output. - ---debug:: - This may help the person who is developing a new test. - It causes the command defined with test_debug to run. - The "trash" directory (used to store all temporary data - during testing) is not deleted even if there are no - failed tests so that you can inspect its contents after - the test finished. - ---immediate:: - This causes the test to immediately exit upon the first - failed test. - ---long-tests:: - This causes additional long-running tests to be run (where - available), for more exhaustive testing. - ---valgrind:: - Execute all Git binaries with valgrind and exit with status - 126 on errors (just like regular tests, this will only stop - the test script when running under -i). Valgrind errors - go to stderr, so you might want to pass the -v option, too. - - Since it makes no sense to run the tests with --valgrind and - not see any output, this option implies --verbose. For - convenience, it also implies --tee. - - Note that valgrind is run with the option --leak-check=no, - as the git process is short-lived and some errors are not - interesting. In order to run a single command under the same - conditions manually, you should set GIT_VALGRIND to point to - the 't/valgrind/' directory and use the commands under - 't/valgrind/bin/'. - ---tee:: - In addition to printing the test output to the terminal, - write it to files named 't/test-results/$TEST_NAME.out'. - As the names depend on the tests' file names, it is safe to - run the tests with this option in parallel. - ---with-dashes:: - By default tests are run without dashed forms of - commands (like git-commit) in the PATH (it only uses - wrappers from ../bin-wrappers). Use this option to include - the build directory (..) in the PATH, which contains all - the dashed forms of commands. This option is currently - implied by other options like --valgrind and - GIT_TEST_INSTALLED. - ---root=:: - Create "trash" directories used to store all temporary data during - testing under , instead of the t/ directory. - Using this option with a RAM-based filesystem (such as tmpfs) - can massively speed up the test suite. - ---chain-lint:: ---no-chain-lint:: - If --chain-lint is enabled, the test harness will check each - test to make sure that it properly "&&-chains" all commands (so - that a failure in the middle does not go unnoticed by the final - exit code of the test). This check is performed in addition to - running the tests themselves. - -You can also set the GIT_TEST_INSTALLED environment variable to -the bindir of an existing git installation to test that installation. -You still need to have built this git sandbox, from which various -test-* support programs, templates, and perl libraries are used. -If your installed git is incomplete, it will silently test parts of -your built version instead. - -When using GIT_TEST_INSTALLED, you can also set GIT_TEST_EXEC_PATH to -override the location of the dashed-form subcommands (what -GIT_EXEC_PATH would be used for during normal operation). -GIT_TEST_EXEC_PATH defaults to `$GIT_TEST_INSTALLED/git --exec-path`. - - -Skipping Tests --------------- - -In some environments, certain tests have no way of succeeding -due to platform limitation, such as lack of 'unzip' program, or -filesystem that do not allow arbitrary sequence of non-NUL bytes -as pathnames. - -You should be able to say something like - - $ GIT_SKIP_TESTS=t9200.8 sh ./t9200-git-cvsexport-commit.sh - -and even: - - $ GIT_SKIP_TESTS='t[0-4]??? t91?? t9200.8' make - -to omit such tests. The value of the environment variable is a -SP separated list of patterns that tells which tests to skip, -and either can match the "t[0-9]{4}" part to skip the whole -test, or t[0-9]{4} followed by ".$number" to say which -particular test to skip. - -Note that some tests in the existing test suite rely on previous -test item, so you cannot arbitrarily disable one and expect the -remainder of test to check what the test originally was intended -to check. - - -Naming Tests ------------- - -The test files are named as: - - tNNNN-commandname-details.sh - -where N is a decimal digit. - -First digit tells the family: - - 0 - the absolute basics and global stuff - 1 - the basic commands concerning database - 2 - the basic commands concerning the working tree - 3 - the other basic commands (e.g. ls-files) - 4 - the diff commands - 5 - the pull and exporting commands - 6 - the revision tree commands (even e.g. merge-base) - 7 - the porcelainish commands concerning the working tree - 8 - the porcelainish commands concerning forensics - 9 - the git tools - -Second digit tells the particular command we are testing. - -Third digit (optionally) tells the particular switch or group of switches -we are testing. - -If you create files under t/ directory (i.e. here) that is not -the top-level test script, never name the file to match the above -pattern. The Makefile here considers all such files as the -top-level test script and tries to run all of them. Care is -especially needed if you are creating a common test library -file, similar to test-lib.sh, because such a library file may -not be suitable for standalone execution. - - -Writing Tests -------------- - -The test script is written as a shell script. It should start -with the standard "#!/bin/sh" with copyright notices, and an -assignment to variable 'test_description', like this: - - #!/bin/sh - # - # Copyright (c) 2005 Junio C Hamano - # - - test_description='xxx test (option --frotz) - - This test registers the following structure in the cache - and tries to run git-ls-files with option --frotz.' - - -Source 'test-lib.sh' --------------------- - -After assigning test_description, the test script should source -test-lib.sh like this: - - . ./test-lib.sh - -This test harness library does the following things: - - - If the script is invoked with command line argument --help - (or -h), it shows the test_description and exits. - - - Creates an empty test directory with an empty .git/objects database - and chdir(2) into it. This directory is 't/trash - directory.$test_name_without_dotsh', with t/ subject to change by - the --root option documented above. - - - Defines standard test helper functions for your scripts to - use. These functions are designed to make all scripts behave - consistently when command line arguments --verbose (or -v), - --debug (or -d), and --immediate (or -i) is given. - -Do's, don'ts & things to keep in mind -------------------------------------- - -Here are a few examples of things you probably should and shouldn't do -when writing tests. - -Do: - - - Put all code inside test_expect_success and other assertions. - - Even code that isn't a test per se, but merely some setup code - should be inside a test assertion. - - - Chain your test assertions - - Write test code like this: - - git merge foo && - git push bar && - test ... - - Instead of: - - git merge hla - git push gh - test ... - - That way all of the commands in your tests will succeed or fail. If - you must ignore the return value of something, consider using a - helper function (e.g. use sane_unset instead of unset, in order - to avoid unportable return value for unsetting a variable that was - already unset), or prepending the command with test_might_fail or - test_must_fail. - - - Check the test coverage for your tests. See the "Test coverage" - below. - - Don't blindly follow test coverage metrics; if a new function you added - doesn't have any coverage, then you're probably doing something wrong, - but having 100% coverage doesn't necessarily mean that you tested - everything. - - Tests that are likely to smoke out future regressions are better - than tests that just inflate the coverage metrics. - - - When a test checks for an absolute path that a git command generated, - construct the expected value using $(pwd) rather than $PWD, - $TEST_DIRECTORY, or $TRASH_DIRECTORY. It makes a difference on - Windows, where the shell (MSYS bash) mangles absolute path names. - For details, see the commit message of 4114156ae9. - -Don't: - - - exit() within a