abra zsh config 2.0

This commit is contained in:
Andrey Anurin
2018-08-12 15:26:21 +03:00
parent 201abd09c4
commit 6b114440e2
1195 changed files with 68948 additions and 10539 deletions

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$Id$
vim:softtabstop=2 shiftwidth=2
-->
<!-- =========================================================================
Functions
-->
<chapter id="functions">
<title>Functions</title>
<para>This XML file is a placeholder. It is meant to be overwritten with the dynamically generated XML document that is extracted from the source code.</para>
</chapter>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$Id$
vim:softtabstop=2 shiftwidth=2
-->
<!-- =========================================================================
Introduction
-->
<chapter label="1" id="introduction">
<title>Introduction</title>
<para>shUnit2 is a unit test framework for Bourne based shell scripts, and it is designed to work in a similar manner to <ulink url="http://www.junit.org/">JUnit</ulink>, <ulink url="http://pyunit.sourceforge.net/">PyUnit</ulink>, etc.</para>
<para>shUnit2 was originally developed to provide a consistent testing solution for <ulink url="http://log4sh.sourceforge.net/">log4sh</ulink>, a shell based logging framework similar to log4j. During the development of that product, the problem of having things work just fine under one shell (<filename>/bin/bash</filename> on Linux to be specific), and then not working under another shell (<filename>/bin/sh</filename> on Solaris), kept coming up. Although there were several simple tests ran, they were not adaquate and did not catch very many corner cases. The decision was finally made to write a proper unit test framework after after multiple brown-bag releases were made.</para>
<para><blockquote><title>Tested Operating Systems</title>
<itemizedlist>
<listitem><para><ulink url="http://www.cygwin.com/">Cygwin</ulink></para></listitem>
<listitem><para><ulink url="http://www.freebsd.org/">FreeBSD</ulink> (user supported)</para></listitem>
<listitem><para>Linux (<ulink url="http://www.gentoo.org/">Gentoo</ulink>, <ulink url="http://www.ubuntu.com/">Ubuntu</ulink>)</para></listitem>
<listitem><para><ulink url="http://www.apple.com/macosx/">Mac OS X</ulink></para></listitem>
<listitem><para><ulink url="http://www.sun.com/software/solaris/">Solaris</ulink> 8, 9, 10</para></listitem>
</itemizedlist>
</blockquote></para>
<para><blockquote><title>Tested Shells</title>
<itemizedlist>
<listitem><para>Bourne Shell (<command>sh</command>)</para></listitem>
<listitem><para><ulink url="http://www.gnu.org/software/bash/">BASH</ulink> - GNU Bourne Again SHell (<command>bash</command>)</para></listitem>
<listitem><para><ulink url="http://gondor.apana.org.au/~herbert/dash/">DASH</ulink> (<command>dash</command>)</para></listitem>
<listitem><para><ulink url="http://www.kornshell.com/">Korn Shell</ulink> (<command>ksh</command>)</para></listitem>
<listitem><para><ulink url="http://web.cs.mun.ca/~michael/pdksh/">pdksh</ulink> - Public Domain Korn Shell (<command>pdksh</command>)</para></listitem>
</itemizedlist>
</blockquote></para>
<para>See the appropriate Release Notes (<filename>doc/RELEASE_NOTES-X.X.X.txt</filename>) for this release for the actual versions tested.</para>
<!-- Give credit where credit is due...very important -->
<section id="credits"><title>Credits / Contributors</title>
<para>A list of contributors to shUnit2 can be found in the source archive as <filename>doc/contributors.txt</filename>. I want to personally thank all those who have contributed to make this a better tool.</para>
</section>
<!-- Feedback -->
<section id="feedback"><title>Feedback</title>
<para>Feedback is most certainly welcome for this document. Send your additions, comments and criticisms to the following email address: <email>&myEmail;</email>.</para>
</section>
</chapter>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$Id: quickstart.xml 230 2006-08-19 22:32:02Z sfsetse $
vim:softtabstop=2 shiftwidth=2
-->
<!-- =========================================================================
Quickstart
-->
<chapter id="quickstart">
<title>Quickstart</title>
<para>This chapter will give a very quick start to running unit tests with shUnit2. More information is located in other chapters.</para>
<para>Here is a quick sample script to show how easy it is to write a unit test in shell. It expects that you have a copy of &shunit2; in the same directory as the script.</para>
<programlisting>
<![CDATA[
#! /bin/sh
testEquality()
{
assertEquals 1 1
}
# load shunit2
. ./shunit2
]]>
</programlisting>
<para>Running the unit test should give results similar to the following.</para>
<screen>
<![CDATA[
#
# Performing tests
#
testEquality
#
# Test report
#
tests passed: 1
tests failed: 0
tests total: 1
success rate: 100%
]]>
</screen>
<para>Wohoo! You've just run your first successful unit test. So, what just happened? Quite a bit really, and it all happened simply by sourcing the &shunit2; script. The basic functionality for the script above goes like this.</para>
<para>When shUnit2 is sourced, it first looks to see if a <function>suite()</function> function has been declared. If it exists, it is called as it is expected to contain a list of tests to be executed. If it doesn't exist (and it doesn't in the above example), shUnit2 will look on its own for any functions that start with the string <literal>test</literal>, and adds those to an internal list of tests to execute. Once a list of test functions to be run has been determined, shunit2 will go to work.</para>
<para>Before any tests are executed, shUnit2 again looks for a function, this time one named <function>oneTimeSetUp()</function>. If it exists, it will be run. This function is normally used to setup the environment for all tests to be run. Things like creating directories for output or setting environment variables are good to place here. Just so you know, you can also declare a corresponding function named <function>oneTimeTearDown()</function> function that does the same thing, but once all the tests have been completed. It is good for removing temporary directories, etc.</para>
<para>shUnit2 is now ready to run tests. Before doing so though, it again looks for another function that might be declared, one named <function>setUp()</function>. If the function exists, it will be run before each test. It is good for resetting the environment so that each test starts with a clean slate. At this stage, the first test is finally run. The success of the test is recorded for a report that will be generated later. After the test is run, shUnit2 looks for a final function that might be declared, one named <function>tearDown()</function>. If it exists, it will be run after each test. It is a good place for cleaning up after each test, maybe doing things like removing files that were created, or removing directories. This set of steps, setUp() &gt; test() &gt; tearDown(), is repeated for all of the available tests.</para>
<para>Once all the work is done, shUnit2 will generate the nice report you saw above. A summary of all the successes and failures will be given so that you know how well your code is doing.</para>
<para>We should now try adding a test that fails. Change your unit test to look like this.</para>
<programlisting>
<![CDATA[
#! /bin/sh
testEquality()
{
assertEquals 1 1
}
testPartyLikeItIs1999()
{
year=`date '+%Y'`
assertEquals "It's not 1999 :-( This is ${year}." \
'1999' "${year}"
}
# load shunit2
. ./shunit2
]]>
</programlisting>
<para>So, what did you get? I guess it told you that this isn't 1999. Bummer, eh? Hopefully, you noticed a couple of things that were different about the second test. First, we added an optional message that the user will see if the assert fails. Second, we did comparisons of strings instead of integers as in the first test. It doesn't matter whether you are testing for equality of strings or integers. Both work equally well with shUnit2.</para>
<para>Hopefully, this is enough to get you started with unit testing. If you want a ton more examples, take a look at the tests provided with <ulink url="http://log4sh.sourceforge.net/">log4sh</ulink>. Examples of much more advanced usage can be seen there. shUnit2 was after all written to help with the unit testing problems that log4sh had.</para>
</chapter>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$Id$
vim: softtabstop=2 shiftwidth=2
-->
<!--
This document can be converted to HTML using the following commands:
$ java -cp xalan-2.6.0.jar \
org.apache.xalan.xslt.Process -xml -in log4sh.xml -xsl tldp-one-page.xsl
$ xsltproc tldp-one-page.xsl log4sh.xml |xmllint -noblanks -
-->
<!DOCTYPE book
PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!ENTITY functions SYSTEM "functions.xml">
<!ENTITY introduction SYSTEM "introduction.xml">
<!ENTITY quickstart SYSTEM "quickstart.xml">
<!ENTITY myEmail "kate.ward@forestent.com">
<!ENTITY isoDate "@@ISO_DATE@@">
<!ENTITY shunit2 "<command>shunit2</command>">
]>
<book id="shUnit2" lang="en-US"><title>shUnit2</title>
<bookinfo>
<title>shUnit2 version 2.0.3</title>
<authorgroup>
<author>
<firstname>Kate</firstname><surname>Ward</surname>
<affiliation>
<address>
<email>&myEmail;</email>
</address>
</affiliation>
</author>
</authorgroup>
<!-- All dates specified in ISO "YYYY-MM-DD" format -->
<pubdate>&isoDate;</pubdate>
<!-- TODO flush out like bookinfo in docbook-tdg -->
<!-- Most recent revision goes at the top; list in descending order -->
<revhistory>
<revision>
<revnumber>2.0.3</revnumber>
<date>2007-07-12</date>
<authorinitials>Kate Ward &lt;&myEmail;&gt;</authorinitials>
</revision>
<revision>
<revnumber>2.0.2</revnumber>
<date>2007-04-22</date>
<authorinitials>Kate Ward &lt;&myEmail;&gt;</authorinitials>
</revision>
<revision>
<revnumber>2.0.1</revnumber>
<date>2007-02-21</date>
<authorinitials>Kate Ward &lt;&myEmail;&gt;</authorinitials>
</revision>
<revision>
<revnumber>2.0.0</revnumber>
<date>2007-02-20</date>
<authorinitials>Kate Ward &lt;&myEmail;&gt;</authorinitials>
</revision>
</revhistory>
<!-- Provide a good abstract; a couple of sentences is sufficient -->
<abstract>
<para><ulink url="http://sourceforge.net/projects/shunit2">shUnit2</ulink> is a unit test framework for Bourne based shell scripts, and it is designed to work in a similar manner to <ulink url="http://www.junit.org/">JUnit</ulink>, <ulink url="http://pyunit.sourceforge.net/">PyUnit</ulink>, etc.</para>
</abstract>
</bookinfo>
&introduction;
&quickstart;
&functions;
</book>

View File

@@ -0,0 +1,799 @@
# $Id$
# vim:syntax=sh:sts=2
# vim:foldmethod=marker:foldmarker=/**,*/
#
#/**
# <?xml version="1.0" encoding="UTF-8"?>
# <s:shelldoc xmlns:s="http://www.forestent.com/projects/shelldoc/xsl/2005.0">
# <s:header>
# shUnit 2.0.4
# Shell Unit Test Framework
#
# http://code.google.com/p/shunit2/
#
# written by Kate Ward &lt;kate.ward@forestent.com&gt;
# released under the LGPL
#
# this module implements a xUnit based unit test framework similar to JUnit
# </s:header>
#*/
# shell flags for shunit:
# u - treat unset variables as an error when performing parameter expansion
__SHUNIT_SHELL_FLAGS='u'
# save the current set of shell flags, and then set some for ourselves
__shunit_oldShellFlags="$-"
for _shunit_shellFlag in `echo "${__SHUNIT_SHELL_FLAGS}" |sed 's/\(.\)/\1 /g'`
do
set -${_shunit_shellFlag}
done
unset _shunit_shellFlag
# constants
__SHUNIT_VERSION='2.0.4pre'
__SHUNIT_TRUE=0
__SHUNIT_FALSE=1
__SHUNIT_ERROR=2
__SHUNIT_ASSERT_MSG_PREFIX='ASSERT:'
for _su_const in `set |grep "^__SHUNIT_" |cut -d= -f1`; do
readonly ${_su_const}
done
unset _su_const
# variables
__shunit_suite=''
__shunit_testsPassed=0
__shunit_testsFailed=0
__shunit_testsTotal=0
#-----------------------------------------------------------------------------
# assert functions
#
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertEquals</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>expected</parameter></paramdef>
# <paramdef>string <parameter>actual</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Asserts that <emphasis>expected</emphasis> and
# <emphasis>actual</emphasis> are equal to one another. The message is
# optional.</para>
# </entry>
# </s:function>
#*/
assertEquals()
{
_su_message=''
if [ $# -eq 3 ]; then
_su_message=$1
shift
fi
_su_expected=${1:-}
_su_actual=${2:-}
shunit_return=${__SHUNIT_TRUE}
if [ "${_su_expected}" = "${_su_actual}" ]; then
_shunit_testPassed
else
failNotEquals "${_su_message}" "${_su_expected}" "${_su_actual}"
shunit_return=${__SHUNIT_FALSE}
fi
unset _su_message _su_expected _su_actual
return ${shunit_return}
}
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertNull</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>value</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Asserts that <emphasis>value</emphasis> is <literal>null</literal>,
# or in shell terms a zero-length string. The message is optional.</para>
# </entry>
# </s:function>
#*/
assertNull()
{
if [ $# -eq 2 ]; then
assertTrue "$1" "[ -z '$2' ]"
else
assertTrue "[ -z '${1:-}' ]"
fi
}
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertNotNull</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>value</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Asserts that <emphasis>value</emphasis> is <emphasis
# role="strong">not</emphasis> <literal>null</literal>, or in shell terms not
# a zero-length string. The message is optional.</para>
# </entry>
# </s:function>
#*/
assertNotNull()
{
if [ $# -eq 2 ]; then
assertTrue "$1" "[ -n '$2' ]"
else
assertTrue "[ -n '${1:-}' ]"
fi
}
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertSame</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>expected</parameter></paramdef>
# <paramdef>string <parameter>actual</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>This function is functionally equivalent to
# <function>assertEquals</function>.</para>
# </entry>
# </s:function>
#*/
assertSame()
{
assertEquals "${@:-}"
}
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertNotSame</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>unexpected</parameter></paramdef>
# <paramdef>string <parameter>actual</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Asserts that <emphasis>unexpected</emphasis> and
# <emphasis>actual</emphasis> are <emphasis role="strong">not</emphasis>
# equal to one another. The message is optional.</para>
# </entry>
# </s:function>
#*/
assertNotSame()
{
_su_message=''
if [ $# -eq 3 ]; then
_su_message=$1
shift
fi
_su_unexpected=${1:-}
_su_actual=${2:-}
shunit_return=${__SHUNIT_TRUE}
if [ "${_su_unexpected}" != "${_su_actual}" ]; then
_shunit_testPassed
else
failSame "${_su_message}"
shunit_return=${__SHUNIT_FALSE}
fi
unset _su_message _su_unexpected _su_actual
return ${shunit_return}
}
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertTrue</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>condition</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Asserts that a given shell test condition is true. The message is
# optional.</para>
# <para>Testing whether something is true or false is easy enough by using
# the assertEquals/assertNotSame functions. Shell supports much more
# complicated tests though, and a means to support them was needed. As such,
# this function tests that conditions are true or false through evaluation
# rather than just looking for a true or false.</para>
# <funcsynopsis>
# The following test will succeed: <funcsynopsisinfo>assertTrue "[ 34 -gt 23 ]"</funcsynopsisinfo>
# The folloing test will fail with a message: <funcsynopsisinfo>assertTrue "test failed" "[ -r '/non/existant/file' ]"</funcsynopsisinfo>
# </funcsynopsis>
# </entry>
# </s:function>
#*/
assertTrue()
{
_su_message=''
if [ $# -eq 2 ]; then
_su_message=$1
shift
fi
_su_condition=${1:-}
shunit_return=${__SHUNIT_TRUE}
# see if condition is an integer, i.e. a return value
_su_match=`expr "${_su_condition}" : '\([0-9]*\)'`
if [ -z "${_su_condition}" ]; then
# null condition
shunit_return=${__SHUNIT_FALSE}
elif [ "${_su_condition}" = "${_su_match}" ]; then
# possible return value. treating 0 as true, and non-zero as false.
[ ${_su_condition} -ne 0 ] && shunit_return=${__SHUNIT_FALSE}
else
# (hopefully) a condition
( eval ${_su_condition} ) >/dev/null 2>&1
[ $? -ne 0 ] && shunit_return=${__SHUNIT_FALSE}
fi
# record the test
if [ ${shunit_return} -eq ${__SHUNIT_TRUE} ]; then
_shunit_testPassed
else
_shunit_testFailed "${_su_message}"
fi
unset _su_message _su_condition _su_match
return ${shunit_return}
}
#/**
# <s:function group="asserts">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>assertFalse</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>condition</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Asserts that a given shell test condition is false. The message is
# optional.</para>
# <para>Testing whether something is true or false is easy enough by using
# the assertEquals/assertNotSame functions. Shell supports much more
# complicated tests though, and a means to support them was needed. As such,
# this function tests that conditions are true or false through evaluation
# rather than just looking for a true or false.</para>
# <funcsynopsis>
# The following test will succeed: <funcsynopsisinfo>assertFalse "[ 'apples' = 'oranges' ]"</funcsynopsisinfo>
# The folloing test will fail with a message: <funcsynopsisinfo>assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]"</funcsynopsisinfo>
# </funcsynopsis>
# </entry>
# </s:function>
#*/
assertFalse()
{
_su_message=''
if [ $# -eq 2 ]; then
_su_message=$1
shift
fi
_su_condition=${1:-}
shunit_return=${__SHUNIT_TRUE}
# see if condition is an integer, i.e. a return value
_su_match=`expr "${_su_condition}" : '\([0-9]*\)'`
if [ -z "${_su_condition}" ]; then
# null condition
shunit_return=${__SHUNIT_FALSE}
elif [ "${_su_condition}" = "${_su_match}" ]; then
# possible return value. treating 0 as true, and non-zero as false.
[ ${_su_condition} -eq 0 ] && shunit_return=${__SHUNIT_FALSE}
else
# (hopefully) a condition
( eval ${_su_condition} ) >/dev/null 2>&1
[ $? -eq 0 ] && shunit_return=${__SHUNIT_FALSE}
fi
# record the test
if [ ${shunit_return} -eq ${__SHUNIT_TRUE} ]; then
_shunit_testPassed
else
_shunit_testFailed "${_su_message}"
fi
unset _su_message _su_condition _su_match
return ${shunit_return}
}
#-----------------------------------------------------------------------------
# failure functions
#
#/**
# <s:function group="failures">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>fail</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Fails the test immediately, with the optional message.</para>
# </entry>
# </s:function>
#*/
fail()
{
_su_message=${1:-}
_shunit_testFailed "${_su_message}"
unset _su_message
}
#/**
# <s:function group="failures">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>failNotEquals</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>unexpected</parameter></paramdef>
# <paramdef>string <parameter>actual</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Fails the test if <emphasis>unexpected</emphasis> and
# <emphasis>actual</emphasis> are <emphasis role="strong">not</emphasis>
# equal to one another. The message is optional.</para>
# </entry>
# </s:function>
#*/
failNotEquals()
{
_su_message=''
if [ $# -eq 3 ]; then
_su_message=$1
shift
fi
_su_unexpected=${1:-}
_su_actual=${2:-}
_shunit_testFailed "${_su_message:+${_su_message} }expected:<${_su_unexpected}> but was:<${_su_actual}>"
unset _su_message _su_unexpected _su_actual
}
#/**
# <s:function group="failures">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>failSame</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Indicate test failure because arguments were not the same. The
# message is optional.</para>
# </entry>
# </s:function>
#*/
failSame()
{
_su_message=${1:-}
_shunit_testFailed "${_su_message:+${_su_message} }expected not same"
unset _su_message
}
#/**
# <s:function group="failures">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>failNotSame</function></funcdef>
# <paramdef>string <parameter>[message]</parameter></paramdef>
# <paramdef>string <parameter>expected</parameter></paramdef>
# <paramdef>string <parameter>actual</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>Fails the test if <emphasis>expected</emphasis> and
# <emphasis>actual</emphasis> are equal to one another. The message is
# optional.</para>
# </entry>
# </s:function>
#*/
failNotSame()
{
failNotEquals "${@:-}"
}
#-----------------------------------------------------------------------------
# suite functions
#
#/**
# <s:function group="suites">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>suite</function></funcdef>
# <paramdef />
# </funcprototype>
# </funcsynopsis>
# <para>This function can be optionally overridden by the user in their test
# suite.</para>
# <para>If this function exists, it will be called when
# <command>shunit2</command> is sourced. If it does not exist, shUnit2 will
# search the parent script for all functions beginning with the word
# <literal>test</literal>, and they will be added dynamically to the test
# suite.</para>
# </entry>
# </s:function>
#*/
# Note: see _shunit_mktempFunc() for actual implementation
# suite() { :; }
#/**
# <s:function group="suites">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>suite_addTest</function></funcdef>
# <paramdef>string <parameter>function</parameter></paramdef>
# </funcprototype>
# </funcsynopsis>
# <para>This function adds a function name to the list of tests scheduled for
# execution as part of this test suite. This function should only be called
# from within the <function>suite()</function> function.</para>
# </entry>
# </s:function>
#*/
suite_addTest()
{
_su_func=${1:-}
__shunit_suite="${__shunit_suite:+${__shunit_suite} }${_su_func}"
unset _su_func
}
#/**
# <s:function group="suites">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>oneTimeSetUp</function></funcdef>
# <paramdef />
# </funcprototype>
# </funcsynopsis>
# <para>This function can be be optionally overridden by the user in their
# test suite.</para>
# <para>If this function exists, it will be called once before any tests are
# run. It is useful to prepare a common environment for all tests.</para>
# </entry>
# </s:function>
#*/
# Note: see _shunit_mktempFunc() for actual implementation
# oneTimeSetUp() { :; }
#/**
# <s:function group="suites">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>oneTimeTearDown</function></funcdef>
# <paramdef />
# </funcprototype>
# </funcsynopsis>
# <para>This function can be be optionally overridden by the user in their
# test suite.</para>
# <para>If this function exists, it will be called once after all tests are
# completed. It is useful to clean up the environment after all tests.</para>
# </entry>
# </s:function>
#*/
# Note: see _shunit_mktempFunc() for actual implementation
# oneTimeTearDown() { :; }
#/**
# <s:function group="suites">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>setUp</function></funcdef>
# <paramdef />
# </funcprototype>
# </funcsynopsis>
# <para>This function can be be optionally overridden by the user in their
# test suite.</para>
# <para>If this function exists, it will be called before each test is run.
# It is useful to reset the environment before each test.</para>
# </entry>
# </s:function>
#*/
# Note: see _shunit_mktempFunc() for actual implementation
# setUp() { :; }
#/**
# <s:function group="suites">
# <entry align="right">
# <emphasis>void</emphasis>
# </entry>
# <entry>
# <funcsynopsis>
# <funcprototype>
# <funcdef><function>tearDown</function></funcdef>
# <paramdef />
# </funcprototype>
# </funcsynopsis>
# <para>This function can be be optionally overridden by the user in their
# test suite.</para>
# <para>If this function exists, it will be called after each test completes.
# It is useful to clean up the environment after each test.</para>
# </entry>
# </s:function>
#*/
# Note: see _shunit_mktempFunc() for actual implementation
# tearDown() { :; }
#------------------------------------------------------------------------------
# internal shUnit2 functions
#
_shunit_cleanup()
{
name=$1
case ${name} in
EXIT) signal=0 ;;
INT) signal=2 ;;
TERM) signal=15 ;;
esac
# do our work
rm -fr "${__shunit_tmpDir}"
# exit for all non-EXIT signals
if [ ${name} != 'EXIT' ]; then
echo "trapped and now handling the ${name} signal" >&2
_shunit_generateReport
# disable EXIT trap
trap 0
# add 128 to signal and exit
exit `expr ${signal} + 128`
fi
}
_shunit_execSuite()
{
echo '#'
echo '# Performing tests'
echo '#'
for _su_func in ${__shunit_suite}; do
# execute the per-test setup function
setUp
# execute the test
echo "${_su_func}"
eval ${_su_func}
# execute the per-test tear-down function
tearDown
done
unset _su_func
}
_shunit_functionExists()
{
_su__func=$1
type ${_su__func} 2>/dev/null |grep "is a function$" >/dev/null
_su__return=$?
unset _su__func
return ${_su__return}
}
_shunit_generateReport()
{
_su__awkPercent='{printf("%0.0f%%", $1*100/$2)}'
if [ ${__shunit_testsTotal} -gt 0 ]; then
_su__success=`echo ${__shunit_testsPassed} ${__shunit_testsTotal} |\
awk "${_su__awkPercent}"`
else
_su__success=0
fi
cat <<EOF
#
# Test report
#
tests passed: ${__shunit_testsPassed}
tests failed: ${__shunit_testsFailed}
tests total: ${__shunit_testsTotal}
success rate: ${_su__success}
EOF
unset _su__success
}
# this function is a cross-platform temporary directory creation tool. not all
# OSes have the mktemp function, so one is included here.
_shunit_mktempDir()
{
# try the standard mktemp function
( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return
# the standard mktemp didn't work. doing our own.
if [ -r '/dev/urandom' -a -x '/usr/bin/od' ]; then
_su__random=`/usr/bin/od -vAn -N4 -tx4 </dev/urandom \
|sed 's/^[^0-9a-f]*//'`
elif [ -n "${RANDOM:-}" ]; then
# $RANDOM works
_su__random=${RANDOM}${RANDOM}${RANDOM}$$
else
# $RANDOM doesn't work
_su__date=`date '+%Y%m%d%H%M%S'`
_su__random=`expr ${_su__date} / $$`
fi
_su__tmpDir="${TMPDIR-/tmp}/shunit.${_su__random}"
( umask 077 && mkdir "${_su__tmpDir}" ) || {
echo 'shUnit:FATAL could not create temporary directory! exiting' >&2
return ${__SHUNIT_ERROR}
}
echo ${_su__tmpDir}
unset _su__date _su__random _su__tmpDir
}
# this function is here to work around issues in Cygwin
_shunit_mktempFunc()
{
for _su__func in oneTimeSetUp oneTimeTearDown setUp tearDown suite; do
_su__file="${__shunit_tmpDir}/${_su__func}"
cat <<EOF >"${_su__file}"
#! /bin/sh
exit 0
EOF
chmod +x "${_su__file}"
done
unset _su__file
}
_shunit_testPassed()
{
__shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
__shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
}
_shunit_testFailed()
{
_su__msg=$1
__shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
__shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_su__msg}" >&2
unset _su__msg
}
#------------------------------------------------------------------------------
# main
#
# create a temporary storage location
__shunit_tmpDir=`_shunit_mktempDir` || exit ${__SHUNIT_ERROR}
# setup traps to clean up after ourselves
trap '_shunit_cleanup EXIT' 0
trap '_shunit_cleanup INT' 2
trap '_shunit_cleanup TERM' 15
# create phantom functions to work around issues with Cygwin
_shunit_mktempFunc
PATH="${__shunit_tmpDir}:${PATH}"
# execute the oneTimeSetUp function (if it exists)
#_shunit_functionExists oneTimeSetUp && oneTimeSetUp
oneTimeSetUp
# deprecated: execute the suite function defined in the parent test script
suite
# if no suite function was defined, dynamically build a list of functions
if [ -z "${__shunit_suite}" ]; then
funcs=`grep "^[ \t]*test[A-Za-z0-9_]* *()" $0 |sed 's/[^A-Za-z0-9_]//g'`
for func in ${funcs}; do
suite_addTest ${func}
done
fi
# execute the tests
_shunit_execSuite
# execute the oneTimeTearDown function (if it exists)
oneTimeTearDown
# generate report
_shunit_generateReport
# restore the previous set of shell flags
for _shunit_shellFlag in ${__SHUNIT_SHELL_FLAGS}; do
echo ${__shunit_oldShellFlags} |grep ${_shunit_shellFlag} >/dev/null \
|| set +${_shunit_shellFlag}
done
unset _shunit_shellFlag
#/**
# </s:shelldoc>
#*/

View File

@@ -0,0 +1,116 @@
#! /bin/sh
# $Id: run-test-suite 432 2007-01-05 14:58:37Z sfsetse $
MY_NAME=`basename $0`
MY_PATH=`dirname $0`
SHELLS='/bin/sh /bin/bash /bin/dash /bin/ksh /bin/pdksh'
for f in test[A-Z]*; do
[ -x "${f}" ] && TESTS="${TESTS:+${TESTS} }${f}"
done
# load common unit test functions
. "${MY_PATH}/test-functions.inc"
usage()
{
echo "usage: ${MY_NAME} [-e key=val ...] [-s shell(s)] [-t test(s)]"
}
# process command line flags
while getopts 'e:hs:t:' opt; do
case ${opt} in
e)
key=`expr "${OPTARG}" : '\([^=]*\)='`
val=`expr "${OPTARG}" : '[^=]*=\(.*\)'`
if [ -z "${key}" -o -z "${val}" ]; then
usage
exit 1
fi
eval "${key}='${val}'"
export ${key}
env="${env:+${env} }${key}"
;;
h) usage; exit 0 ;;
s) shells=${OPTARG} ;;
t) tests=${OPTARG} ;;
*) usage; exit 1 ;;
esac
done
shift `expr ${OPTIND} - 1`
# fill shells and/or tests
shells=${shells:-${SHELLS}}
tests=${tests:-${TESTS}}
# error checking
if [ -z "${tests}" ]; then
tf_error 'no tests found to run; exiting'
exit 1
fi
cat <<EOF
#------------------------------------------------------------------------------
# System data
#
# test run info
shells="${shells}"
tests="${tests}"
EOF
for key in ${env}; do
eval "echo \"${key}=\$${key}\""
done
echo
# output system data
echo "# system info"
echo "$ date"
date
echo "$ uname -mprsv"
uname -mprsv
#
# run tests
#
for shell in ${shells}; do
echo
# check for existance of shell
if [ ! -x ${shell} ]; then
tf_warn "unable to run tests with the ${shell} shell"
continue
fi
cat <<EOF
#------------------------------------------------------------------------------
# Running the test suite with ${shell}
#
EOF
case `basename ${shell}` in
bash) echo; ${shell} --version; ;;
dash) ;;
ksh)
version=`${shell} --version exit 2>&1`
exitVal=$?
if [ ${exitVal} -eq 2 ]; then
echo
echo "${version}"
fi
;;
pdksh) ;;
zsh) ;;
esac
# execute the tests
for suite in ${tests}; do
suiteName=`expr "${suite}" : 'test\(.*\)'`
echo
echo "--- Executing the '${suiteName}' test suite ---" >&2
( exec ${shell} ./${suite}; )
done
done

View File

@@ -0,0 +1,84 @@
# $Id: test-functions.inc 416 2007-01-04 00:50:14Z sfsetse $
# vim:syntax=sh:sts=2
#
# constants
#
# configure debugging. set the DEBUG environment variable to any
# non-empty value to enable debug output, or TRACE to enable trace
# output.
TRACE=${TRACE:+'tf_trace '}
[ -n "${TRACE}" ] && DEBUG=1
[ -z "${TRACE}" ] && TRACE=':'
DEBUG=${DEBUG:+'tf_debug '}
[ -z "${DEBUG}" ] && DEBUG=':'
#
# variables
#
tf_RANDOM=0
#
# functions
#
# message functions
tf_trace() { echo "${MY_NAME}:TRACE $@" >&2; }
tf_debug() { echo "${MY_NAME}:DEBUG $@" >&2; }
tf_info() { echo "${MY_NAME}:INFO $@" >&2; }
tf_warn() { echo "${MY_NAME}:WARN $@" >&2; }
tf_error() { echo "${MY_NAME}:ERROR $@" >&2; }
tf_fatal() { echo "${MY_NAME}:FATAL $@" >&2; }
# generate a random number
tf_generateRandom()
{
tfgr_random=${tf_RANDOM}
while [ "${tfgr_random}" = "${tf_RANDOM}" ]; do
if [ -n "${RANDOM:-}" ]; then
# $RANDOM works
tfgr_random=${RANDOM}${RANDOM}${RANDOM}$$
elif [ -r '/dev/urandom' ]; then
tfgr_random=`od -vAn -N4 -tu4 </dev/urandom |sed 's/^[^0-9]*//'`
else
tfgr_date=`date '+%H%M%S'`
tfgr_random=`expr ${tfgr_date} \* $$`
unset tfgr_date
fi
[ "${tfgr_random}" = "${tf_RANDOM}" ] && sleep 1
done
tf_RANDOM=${tfgr_random}
unset tfgr_random
}
# this section returns the data section from the specified section of a file. a
# datasection is defined by a [header], one or more lines of data, and then a
# blank line.
tf_getDataSect()
{
tf_sgrep "\\[$1\\]" "$2" |sed '1d'
}
# this function greps a section from a file. a section is defined as a group of
# lines preceeded and followed by blank lines.
tf_sgrep()
{
tf_pattern=$1
shift
sed -e '/./{H;$!d;}' -e "x;/${tf_pattern}/"'!d;' $@ |sed '1d'
unset tf_pattern
}
#
# main
#
${TRACE} 'trace output enabled'
${DEBUG} 'debug output enabled'

View File

@@ -0,0 +1,242 @@
#! /bin/sh
# $Id$
# vim: expandtab
# author: Kate Ward <kate.ward@forestent.com>
#
# Self-testing unit tests for shUnit2 asserts
#
MSG='This is a test message'
#-----------------------------------------------------------------------------
# suite tests
#
commonEqualsSame()
{
fn=$1
msg='same, with message'
rslt=`${fn} "${MSG}" 'x' 'x' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='same'
rslt=`${fn} 'x' 'x' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='not same'
rslt=`${fn} 'x' 'y' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='null values'
rslt=`${fn} '' '' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='too few arguments'
rslt=`${fn} 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
}
testAssertEquals()
{
commonEqualsSame 'assertEquals'
}
testAssertSame()
{
commonEqualsSame 'assertSame'
}
testAssertNotSame()
{
msg='not same, with message'
rslt=`assertNotSame "${MSG}" 'x' 'y' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='not same'
rslt=`assertNotSame 'x' 'y' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='same'
rslt=`assertNotSame 'x' 'x' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='null values'
rslt=`assertNotSame '' '' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='too few arguments'
rslt=`assertNotSame 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
}
testAssertNull()
{
msg='null, with message'
rslt=`assertNull "${MSG}" '' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='null'
rslt=`assertNull '' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='not null'
rslt=`assertNull 'x' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='too few arguments'
rslt=`assertNull 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
}
testAssertNotNull()
{
msg='not null, with message'
rslt=`assertNotNull "${MSG}" 'x' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='not null'
rslt=`assertNotNull 'x' 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='null'
rslt=`assertNotNull '' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='too few arguments'
rslt=`assertNotNull 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
}
testAssertTrue()
{
msg='true, with message'
rslt=`assertTrue "${MSG}" 0 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='true'
rslt=`assertTrue 0 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='true condition'
rslt=`assertTrue "[ 0 -eq 0 ]" 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='false'
rslt=`assertTrue 1 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='false condition'
rslt=`assertTrue "[ 0 -eq 1 ]" 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='null value'
rslt=`assertTrue '' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='too few arguments'
rslt=`assertTrue 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
}
testAssertFalse()
{
msg='false, with message'
rslt=`assertFalse "${MSG}" 1 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='false'
rslt=`assertFalse 1 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='false condition'
rslt=`assertFalse "[ 0 -eq 1 ]" 2>&1`
rtrn=$?
assertSame "${msg}" '' "${rslt}"
assertTrue "${msg}; failure" ${rtrn}
msg='true'
rslt=`assertFalse 0 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='true condition'
rslt=`assertFalse "[ 0 -eq 0 ]" 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='null value'
rslt=`assertFalse '' 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
msg='too few arguments'
rslt=`assertFalse 2>&1`
rtrn=$?
assertNotSame "${msg}" '' "${rslt}"
assertFalse "${msg}; failure" ${rtrn}
}
#-----------------------------------------------------------------------------
# suite functions
#
# load and run shUnit2
. ./shunit2

View File

@@ -0,0 +1,89 @@
#! /bin/sh
# $Id$
# vim: expandtab
# author: Kate Ward <kate.ward@forestent.com>
#
# Self-testing unit tests for shUnit2 failures
#
MSG='This is a test message'
#-----------------------------------------------------------------------------
# suite tests
#
commonNotEqualsSame()
{
fn=$1
msg='same, with message'
rslt=`${fn} "${MSG}" 'x' 'x' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='same'
rslt=`${fn} 'x' 'x' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='not same'
rslt=`${fn} 'x' 'y' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='null values'
rslt=`${fn} '' '' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='too few arguments'
rslt=`${fn} 2>&1`
assertNotSame "${msg}" '' "${rslt}"
}
testFail()
{
msg='with message'
rslt=`fail "${MSG}" 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='without message'
rslt=`fail 2>&1`
assertNotSame "${msg}" '' "${rslt}"
}
testFailNotEquals()
{
commonNotEqualsSame 'failNotEquals'
}
testFailSame()
{
msg='same, with message'
rslt=`failSame "${MSG}" 'x' 'x' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='same'
rslt=`failSame 'x' 'x' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='not same'
rslt=`failSame 'x' 'y' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='null values'
rslt=`failSame '' '' 2>&1`
assertNotSame "${msg}" '' "${rslt}"
msg='too few arguments'
rslt=`failSame 2>&1`
assertNotSame "${msg}" '' "${rslt}"
}
testFailNotSame()
{
commonNotEqualsSame 'failNotSame'
}
#-----------------------------------------------------------------------------
# suite functions
#
# load and run shUnit2
. ./shunit2

View File

@@ -0,0 +1,23 @@
#! /bin/sh
# $Id$
# vim: expandtab
# author: Kate Ward <kate.ward@forestent.com>
#
# Self-testing unit tests for shUnit2 internal functions
#
#-----------------------------------------------------------------------------
# suite tests
#
testGenerateReport()
{
:
}
#-----------------------------------------------------------------------------
# suite functions
#
# load and run shUnit2
. ./shunit2

View File

@@ -0,0 +1,23 @@
#! /bin/sh
# $Id$
# vim: expandtab
# author: Kate Ward <kate.ward@forestent.com>
#
# Self-testing unit tests for shUnit2 suite functions
#
#-----------------------------------------------------------------------------
# suite tests
#
testAddTest()
{
:
}
#-----------------------------------------------------------------------------
# suite functions
#
# load and run shUnit2
. ./shunit2