uci
uci_config.h
-test/save
+tests/shunit2/save
+++ /dev/null
-all:
- sh ./tests.sh
+++ /dev/null
-This test script uses shunit2 :
-http://code.google.com/p/shunit2/
-
-uci-static binary is used during tests.
-
-
-How to add a test
-=================
-
-* Test files are located in './test/tests.d'
-
-* These files contain shell functions beginning with 'test' :
-"
-test_get_option ()
-{
-...
-}
-...
-"
-
-* shunit2 functions can be used in these functions :
-http://shunit2.googlecode.com/svn/trunk/source/2.1/doc/shunit2.html
-
-* Additional environment variables are available :
- - ${CONFIG_DIR} : uci search path for config files. This directory is
- reset after each test.
- - ${CHANGES_DIR} : uci search path for config change files. This directory is
- reset after each test.
- - ${TMP_DIR} : path to a directory where can be stored temporary files
- during tests. This directory is reset after each test.
- - ${UCI} : uci static binary called with above config and changes
- directories as parameters.
- - ${REF_DIR} : path to a directory where can be stored reference files
- or data.
+++ /dev/null
-config 'alias' 'a'
- option 'interface' 'lan'
-
-config 'alias' 'b'
- option 'interface' 'lan'
-
-config 'interface' 'lan'
- option 'proto' 'static'
- option 'ifname' 'eth0'
- option 'test' '123'
- option 'enabled' 'off'
- option 'ipaddr' '2.3.4.5'
-
-config 'interface' 'wan'
- option 'proto' 'dhcp'
- option 'ifname' 'eth1'
- option 'enabled' 'on'
- option 'aliases' 'c d'
-
-config 'alias' 'c'
- option 'interface' 'wan'
-
-config 'alias' 'd'
- option 'interface' 'wan'
-
+++ /dev/null
-list_test_config.SEC0='section'
-list_test_config.SEC0.list0+='value0'
-list_test_config.SEC0.list0+='"Hello
-, world"'
+++ /dev/null
-
-config section 'SEC0'
- list list0 'value0'
- list list0 '"Hello
-, world"'
-
+++ /dev/null
-list_test_config.SEC0=section
-list_test_config.SEC0.list0='value0' '"Hello
-, world"'
+++ /dev/null
-+add.section='type'
+++ /dev/null
-
-config section 'SEC0'
- option option0 'value0'
- option option1 '"Hello,
- World"'
-
-config section 'SEC1'
- option option0 'value1'
-
+++ /dev/null
-
-config section 'SEC0'
- option option0 'value0'
- option option1 '"Hello,
- World"'
-
-config section 'SEC1'
- option option0 'value1'
-
+++ /dev/null
-
-config sectype 'sec0'
- list li0 '1'
- list li0 '0'
-
+++ /dev/null
-package delta
-
-config sectype 'sec0'
- list li0 '0'
- list li0 '1'
+++ /dev/null
-
-config section 'SEC0'
- list list0 '"Hello
-, world"'
-
+++ /dev/null
-
-config section 'SEC0'
- list list0 'value0'
-
+++ /dev/null
-
-config 'type' 'section'
- option 'opt' 'val'
- list 'list_opt' 'val0'
- list 'list_opt' 'val1'
- option mul_line_opt_sq 'line 1
-line 2 \
-line 3'
- option mul_line_opt_dq "\"Hello\, \
-World.\'
-"
+++ /dev/null
-package export
-
-config type 'section'
- option opt 'val'
- list list_opt 'val0'
- list list_opt 'val1'
- option mul_line_opt_sq 'line 1
-line 2 \
-line 3'
- option mul_line_opt_dq '"Hello, World.'\''
-'
-
+++ /dev/null
-config 'type' 'section'
- option 'opt' 'val'
+++ /dev/null
-config 'type' 'section'
- # Cannot preserve trailling whitespace with assertEquals.
- option opt "\"Hello, \
-World.
-\'"
+++ /dev/null
-config 'type' 'section'
- option 'opt' 'val'
-
-config 'unnamed'
- option 'opt1' 'val1'
+++ /dev/null
-package 'import-test'
-
-config 'type' 'section'
- option 'opt' 'val'
- list 'list_opt' 'val0'
- list 'list_opt' 'val1'
- option mul_line_opt_sq \''line 1
-line 2 \
-line 3'\'
- option mul_line_opt_dq "\"Hello, \
-World.\'
-"
+++ /dev/null
-
-config type 'section'
- option opt 'val'
- list list_opt 'val0'
- list list_opt 'val1'
- option mul_line_opt_sq ''\''line 1
-line 2 \
-line 3'\'''
- option mul_line_opt_dq '"Hello, World.'\''
-'
-
+++ /dev/null
-revert.SEC0='section'
-revert.SEC0.option1='"Hello,
- World"'
+++ /dev/null
-revert.SEC0='section'
-revert.SEC0.option0='value0'
+++ /dev/null
-config 'named' 'section'
- option 'opt' 'err'
+++ /dev/null
-set.section.opt='val'
+++ /dev/null
-set.section.opt='Hello,\'\''
-World"'
+++ /dev/null
-set.section='named'
+++ /dev/null
-config 'named' 'section'
+++ /dev/null
-set.section.opt='val'
+++ /dev/null
-set.section.opt='Hello,\'\''
-World"'
+++ /dev/null
-config 'type' 'section'
- option 'opt' 'val'
+++ /dev/null
-config 'type' 'section'
- option 'opt' 'val'
+++ /dev/null
-config 'type' 'section'
- option 'opt' 'val'
+++ /dev/null
-config main
- option version 1.4.1
-
-config sockd 'instance0'
- option enabled 1
- list internal_network vpn
- list external_network wan
-
- option extra_config '
- user.unprivileged: nobody
- client pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- session.max: 64
- log: error
- }
-
- socks pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- log: connect
- } '
+++ /dev/null
-sockd.instance0.extra_config='
- user.unprivileged: nobody
- client pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- session.max: 64
- log: error
- }
-
- socks pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- log: connect
- } '
+++ /dev/null
-sockd.@main[0]=main
-sockd.@main[0].version='1.4.1'
-sockd.instance0=sockd
-sockd.instance0.enabled='1'
-sockd.instance0.internal_network='vpn'
-sockd.instance0.external_network='wan'
-sockd.instance0.extra_config='
- user.unprivileged: nobody
- client pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- session.max: 64
- log: error
- }
-
- socks pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- log: connect
- } '
+++ /dev/null
-sockd.instance0=sockd
-sockd.instance0.enabled='1'
-sockd.instance0.internal_network='vpn'
-sockd.instance0.external_network='wan'
-sockd.instance0.extra_config='
- user.unprivileged: nobody
- client pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- session.max: 64
- log: error
- }
-
- socks pass {
- from: 0.0.0.0/0 to: 0.0.0.0/0
- log: connect
- } '
+++ /dev/null
-New network section 'lan'
- type: static
- ifname: eth0
- ipaddr: 2.3.4.5
- test: 123
- enabled: off
-New alias: a
-New alias: b
-New network section 'wan'
- type: dhcp
- ifname: eth1
- ipaddr: 0.0.0.0
- test: -1
- enabled: on
-Configured aliases: c d
+++ /dev/null
-New network section 'lan'
- type: static
- ifname: eth0
- ipaddr: 0.0.0.0
- test: 123
- enabled: off
-Configured aliases: a b
-New network section 'wan'
- type: dhcp
- ifname: eth1
- ipaddr: 0.0.0.0
- test: -1
- enabled: on
-Configured aliases: c d
+++ /dev/null
-# $Id: shunit2 189 2008-07-11 11:46:54Z kate.ward@forestent.com $
-# vim:et:ft=sh:sts=2:sw=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.1.4
-# Shell Unit Test Framework
-#
-# http://shunit2.sourceforge.net/
-#
-# written by Kate Ward <kate.ward@forestent.com>
-# released under the LGPL
-#
-# this module implements a xUnit based unit test framework similar to JUnit
-# </s:header>
-#*/
-
-SHUNIT_VERSION='2.1.4'
-
-_shunit_warn() { echo "shunit2:WARN $@" >&2; }
-_shunit_error() { echo "shunit2:ERROR $@" >&2; }
-_shunit_fatal() { echo "shunit2:FATAL $@" >&2; }
-
-SHUNIT_TRUE=0
-SHUNIT_FALSE=1
-SHUNIT_ERROR=2
-
-# specific shell checks
-if [ -n "${ZSH_VERSION:-}" ]; then
- setopt |grep "^shwordsplit$" >/dev/null
- if [ $? -ne ${SHUNIT_TRUE} ]; then
- _shunit_fatal 'zsh shwordsplit option is required for proper operation'
- exit ${SHUNIT_ERROR}
- fi
- if [ -z "${SHUNIT_PARENT:-}" ]; then
- _shunit_fatal "zsh does not pass \$0 through properly. please declare \
-\"SHUNIT_PARENT=\$0\" before calling shUnit2"
- exit ${SHUNIT_ERROR}
- fi
-fi
-
-# shell flags for shunit2:
-# 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 ourself
-shunit_shellFlags_="$-"
-for shunit_shellFlag_ in `echo "${__SHUNIT_SHELL_FLAGS}" |sed 's/\(.\)/\1 /g'`
-do
- set -${shunit_shellFlag_}
-done
-
-#
-# constants
-#
-
-__SHUNIT_ASSERT_MSG_PREFIX='ASSERT:'
-__SHUNIT_PARENT=${SHUNIT_PARENT:-$0}
-
-# set the constants readonly
-shunit_constants_=`set |grep "^__SHUNIT_" |cut -d= -f1`
-echo "${shunit_constants_}" |grep "^Binary file" >/dev/null
-if [ $? -eq 0 ]; then
- # deal with binary junk in 'set' output
- shunit_constants_=`set |grep -a "^__SHUNIT_" |cut -d= -f1`
-fi
-for shunit_const_ in ${shunit_constants_}; do
- shunit_ro_opts_=''
- if [ -n "${ZSH_VERSION:-}" ]; then
- case ${ZSH_VERSION} in
- [123].*) ;;
- *) shunit_ro_opts_='-g' ;; # declare readonly constants globally
- esac
- fi
- readonly ${shunit_ro_opts_} ${shunit_const_}
-done
-unset shunit_const_ shunit_constants_ shunit_ro_opts_
-
-# variables
-__shunit_skip=${SHUNIT_FALSE}
-__shunit_suite=''
-
-__shunit_testsPassed=0
-__shunit_testsFailed=0
-__shunit_testsSkipped=0
-__shunit_testsTotal=0
-
-# macros
-_SHUNIT_LINENO_='eval if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && shunit_message_="[$2]"; shift 2; fi'
-
-#-----------------------------------------------------------------------------
-# 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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 2 -o $# -gt 3 ]; then
- _shunit_error 'assertEquals() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
- shunit_expected_=$1
- shunit_actual_=$2
-
- shunit_return=${SHUNIT_TRUE}
- if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
- _shunit_testPassed
- else
- failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
- shunit_return=${SHUNIT_FALSE}
- fi
-
- unset shunit_message_ shunit_expected_ shunit_actual_ __shunit_lineno
- return ${shunit_return}
-}
-_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 1 -o $# -gt 2 ]; then
- _shunit_error 'assertNull() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 2 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
- if [ $# -eq 2 ]; then
- assertTrue "${shunit_message_}$1" "[ -z '$2' ]"
- else
- assertTrue "[ -z '$1' ]"
- fi
-}
-_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -gt 2 ]; then # allowing 0 arguments as $1 might actually be null
- _shunit_error 'assertNotNull() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- if [ $# -eq 2 ]; then
- assertTrue "$1" "[ -n '$2' ]"
- else
- assertTrue "[ -n '${1:-}' ]"
- fi
-}
-_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 2 -o $# -gt 3 ]; then
- _shunit_error 'assertSame() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- if [ $# -eq 2 ]; then
- assertEquals "$1" "$2"
- else
- assertEquals "$1" "$2" "$3"
- fi
-}
-_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 2 -o $# -gt 3 ]; then
- _shunit_error 'assertNotSame() requires two or three arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
- shunit_unexpected_=$1
- shunit_actual_=$2
-
- shunit_return=${SHUNIT_TRUE}
- if [ "${shunit_unexpected_}" != "${shunit_actual_}" ]; then
- _shunit_testPassed
- else
- failSame "${shunit_message_}" "$@"
- shunit_return=${SHUNIT_FALSE}
- fi
-
- unset shunit_message_ shunit_unexpected_ shunit_actual_
- return ${shunit_return}
-}
-_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -gt 2 ]; then
- _shunit_error 'assertTrue() takes one two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 2 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
- shunit_condition_=$1
-
- # see if condition is an integer, i.e. a return value
- shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
- shunit_return=${SHUNIT_TRUE}
- if [ -z "${shunit_condition_}" ]; then
- # null condition
- shunit_return=${SHUNIT_FALSE}
- elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then
- # possible return value. treating 0 as true, and non-zero as false.
- [ ${shunit_condition_} -ne 0 ] && shunit_return=${SHUNIT_FALSE}
- else
- # (hopefully) a condition
- ( eval ${shunit_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 "${shunit_message_}"
- fi
-
- unset shunit_message_ shunit_condition_ shunit_match_
- return ${shunit_return}
-}
-_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 1 -o $# -gt 2 ]; then
- _shunit_error 'assertFalse() quires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 2 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
- shunit_condition_=$1
-
- # see if condition is an integer, i.e. a return value
- shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
- shunit_return=${SHUNIT_TRUE}
- if [ -z "${shunit_condition_}" ]; then
- # null condition
- shunit_return=${SHUNIT_FALSE}
- elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then
- # possible return value. treating 0 as true, and non-zero as false.
- [ ${shunit_condition_} -eq 0 ] && shunit_return=${SHUNIT_FALSE}
- else
- # (hopefully) a condition
- ( eval ${shunit_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 "${shunit_message_}"
- fi
-
- unset shunit_message_ shunit_condition_ shunit_match_
- return ${shunit_return}
-}
-_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"'
-
-#-----------------------------------------------------------------------------
-# 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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -gt 1 ]; then
- _shunit_error 'fail() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 1 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
-
- _shunit_testFailed "${shunit_message_}"
-
- unset shunit_message_
- return ${SHUNIT_FALSE}
-}
-_FAIL_='eval fail --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 2 -o $# -gt 3 ]; then
- _shunit_error 'failNotEquals() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
- shunit_unexpected_=$1
- shunit_actual_=$2
-
- _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected:<${shunit_unexpected_}> but was:<${shunit_actual_}>"
-
- unset shunit_message_ shunit_unexpected_ shunit_actual_
- return ${SHUNIT_FALSE}
-}
-_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 2 -o $# -gt 3 ]; then
- _shunit_error 'failSame() requires two or three arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- [ -z "${shunit_message_:-}" ] && shunit_message_=''
- if [ $# -eq 3 ]; then
- shunit_message_="${shunit_message_}$1"
- shift
- fi
-
- _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected not same"
-
- unset shunit_message_
- return ${SHUNIT_FALSE}
-}
-_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"'
-
-#/**
-# <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()
-{
- ${_SHUNIT_LINENO_}
- if [ $# -lt 2 -o $# -gt 3 ]; then
- _shunit_error 'failNotEquals() requires one or two arguments'
- return ${SHUNIT_ERROR}
- fi
- _shunit_shouldSkip && return ${SHUNIT_TRUE}
-
- if [ $# -eq 2 ]; then
- failNotEquals "$1" "$2"
- else
- failNotEquals "$1" "$2" "$3"
- fi
-}
-_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"'
-
-#-----------------------------------------------------------------------------
-# skipping functions
-#
-
-#/**
-# <s:function group="skipping">
-# <entry align="right">
-# <emphasis>void</emphasis>
-# </entry>
-# <entry>
-# <funcsynopsis>
-# <funcprototype>
-# <funcdef><function>startSkipping</function></funcdef>
-# <paramdef />
-# </funcprototype>
-# </funcsynopsis>
-# <para>This function forces the remaining assert and fail functions to be
-# "skipped", i.e. they will have no effect. Each function skipped will be
-# recorded so that the total of asserts and fails will not be altered.</para>
-# </entry>
-# </s:function>
-#*/
-startSkipping()
-{
- __shunit_skip=${SHUNIT_TRUE}
-}
-
-#/**
-# <s:function group="skipping">
-# <entry align="right">
-# <emphasis>void</emphasis>
-# </entry>
-# <entry>
-# <funcsynopsis>
-# <funcprototype>
-# <funcdef><function>endSkipping</function></funcdef>
-# <paramdef />
-# </funcprototype>
-# </funcsynopsis>
-# <para>This function returns calls to the assert and fail functions to their
-# default behavior, i.e. they will be called.</para>
-# </entry>
-# </s:function>
-#*/
-endSkipping()
-{
- __shunit_skip=${SHUNIT_FALSE}
-}
-
-#/**
-# <s:function group="skipping">
-# <entry align="right">
-# <emphasis>boolean</emphasis>
-# </entry>
-# <entry>
-# <funcsynopsis>
-# <funcprototype>
-# <funcdef><function>isSkipping</function></funcdef>
-# <paramdef />
-# </funcprototype>
-# </funcsynopsis>
-# <para>This function returns the state of skipping.</para>
-# </entry>
-# </s:function>
-#*/
-isSkipping()
-{
- return ${__shunit_skip}
-}
-
-#-----------------------------------------------------------------------------
-# 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 ;;
- *)
- _shunit_warn "unrecognized trap value (${name})"
- signal=0
- ;;
- esac
-
- # do our work
- rm -fr "${__shunit_tmpDir}"
-
- # exit for all non-EXIT signals
- if [ ${name} != 'EXIT' ]; then
- _shunit_warn "trapped and now handling the (${name}) signal"
- _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
- # disable skipping
- endSkipping
-
- # 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_generateReport()
-{
- _su__awkPercent='{printf("%4d %3.0f%%", $1, $1*100/$2)}'
- if [ ${__shunit_testsTotal:-0} -gt 0 ]; then
- _su__passed=`echo ${__shunit_testsPassed} ${__shunit_testsTotal} |\
- awk "${_su__awkPercent}"`
- _su__failed=`echo ${__shunit_testsFailed} ${__shunit_testsTotal} |\
- awk "${_su__awkPercent}"`
- _su__skipped=`echo ${__shunit_testsSkipped} ${__shunit_testsTotal} |\
- awk "${_su__awkPercent}"`
- _su__total=`echo ${__shunit_testsTotal} 100 |\
- awk '{printf("%4d %3d%%", $1, $2)}'`
- else
- _su__passed=`echo 0 0 |awk '{printf("%4d %3d%%", $1, $2)}'`
- _su__failed=${_su__passed}
- _su__skipped=${_su__passed}
- _su__total=${_su__passed}
- fi
-
- cat <<EOF
-
-#
-# Test report
-#
-tests passed: ${_su__passed}
-tests failed: ${_su__failed}
-tests skipped: ${_su__skipped}
-tests total: ${_su__total}
-EOF
-
- unset _su__awkPercent _su__passed _su__failed _su__skipped _su__total
-}
-
-# 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' ]; then
- _su__random=`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
- exit 1
- }
-
- 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_shouldSkip()
-{
- [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}
- _shunit_testSkipped
-}
-
-_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
-}
-
-_shunit_testSkipped()
-{
- __shunit_testsSkipped=`expr ${__shunit_testsSkipped} + 1`
- __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
-}
-
-#------------------------------------------------------------------------------
-# main
-#
-
-# create a temporary storage location
-__shunit_tmpDir=`_shunit_mktempDir`
-
-# 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)
-oneTimeSetUp
-
-# execute the suite function defined in the parent test script
-# deprecated as of 2.1.0
-suite
-
-# if no suite function was defined, dynamically build a list of functions
-if [ -z "${__shunit_suite}" ]; then
- shunit_funcs_=`grep "^[ \t]*test[A-Za-z0-9_]* *()" ${__SHUNIT_PARENT} \
- |sed 's/[^A-Za-z0-9_]//g'`
- for shunit_func_ in ${shunit_funcs_}; do
- suite_addTest ${shunit_func_}
- done
-fi
-unset shunit_func_ shunit_funcs_
-
-# 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_shellFlags_} |grep ${shunit_shellFlag_} >/dev/null \
- || set +${shunit_shellFlag_}
-done
-unset shunit_shellFlag_ shunit_shellFlags_
-
-[ ${__shunit_testsFailed} -eq 0 ] || exit 1
-
-#/**
-# </s:shelldoc>
-#*/
+++ /dev/null
-test_import ()
-{
- ${UCI} import < ${REF_DIR}/import.data
- assertSameFile ${REF_DIR}/import.result ${CONFIG_DIR}/import-test
-}
+++ /dev/null
-test_export ()
-{
- cp ${REF_DIR}/export.data ${CONFIG_DIR}/export
-
- ${UCI_Q} export nilpackage
- assertFalse $?
-
- ${UCI_Q} export export 1>/dev/null 2>&1
- assertTrue $?
-
- ${UCI} export > ${TMP_DIR}/export.result
- assertTrue $?
- assertSameFile ${REF_DIR}/export.result ${TMP_DIR}/export.result
-}
+++ /dev/null
-test_get_parsing()
-{
- cp ${REF_DIR}/get_parsing.data ${CONFIG_DIR}/test
-
- assertFailWithNoReturn "${UCI_Q} get test."
- assertFailWithNoReturn "${UCI_Q} get test.section."
- assertFailWithNoReturn "${UCI_Q} get test.section.opt."
- assertFailWithNoReturn "${UCI_Q} get test.section.opt.val."
- assertFailWithNoReturn "${UCI_Q} get test.section.opt.val.qsdf.qsd"
- assertFailWithNoReturn "${UCI_Q} get test.section.opt.valqsqsd"
-}
-
-test_get_section_index_parsing()
-{
- cp ${REF_DIR}/get_parsing.data ${CONFIG_DIR}/test
-
- assertFailWithNoReturn "${UCI_Q} get test.@"
- assertFailWithNoReturn "${UCI_Q} get test.@zer."
- assertFailWithNoReturn "${UCI_Q} get test.@."
- assertFailWithNoReturn "${UCI_Q} get test.@zer[1]"
- assertFailWithNoReturn "${UCI_Q} get test.@.opt"
- assertFailWithNoReturn "${UCI_Q} get test.@[28]"
- assertFailWithNoReturn "${UCI_Q} get test.@[1]."
- assertFailWithNoReturn "${UCI_Q} get test.@[1].val."
-}
-
-test_get_option()
-{
- cp ${REF_DIR}/get.data ${CONFIG_DIR}/test
- value=$($UCI get test.section.opt)
- assertEquals 'val' "$value"
-}
-
-test_get_option_multiline()
-{
- cp ${REF_DIR}/get_multiline.data ${CONFIG_DIR}/test
- value="$($UCI get test.section.opt)"
- assertEquals '"Hello, World.
-'\''' "$value"
-}
-
-test_get_section()
-{
- cp ${REF_DIR}/get.data ${CONFIG_DIR}/test
- type=$($UCI get test.section)
- assertEquals 'type' "$type"
-}
+++ /dev/null
-test_set_parsing()
-{
- cp ${REF_DIR}/set_parsing.data ${CONFIG_DIR}/test
-
- assertFailWithNoReturn "${UCI_Q} set test.=val"
- assertFailWithNoReturn "${UCI_Q} set test.section.=val"
- assertFailWithNoReturn "${UCI_Q} set test.section.opt.=val"
- assertFailWithNoReturn "${UCI_Q} set test.section.opt.zflk=val"
-}
-
-test_set_named_section()
-{
- touch ${CONFIG_DIR}/set
- ${UCI} set set.section=named
- assertSameFile ${REF_DIR}/set_named_section.result ${CHANGES_DIR}/set
-}
-
-test_set_nonexisting_option()
-{
- cp ${REF_DIR}/set_nonexisting_option.data ${CONFIG_DIR}/set
- ${UCI} set set.section.opt=val
- assertSameFile ${REF_DIR}/set_nonexisting_option.result ${CHANGES_DIR}/set
-}
-
-test_set_nonexisting_option_multiline()
-{
- cp ${REF_DIR}/set_nonexisting_option.data ${CONFIG_DIR}/set
- ${UCI} set set.section.opt="Hello,\'
-World\""
- assertSameFile ${REF_DIR}/set_nonexisting_option_multiline.result ${CHANGES_DIR}/set
-}
-
-test_set_existing_option()
-{
- cp ${REF_DIR}/set_existing_option.data ${CONFIG_DIR}/set
- ${UCI} set set.section.opt=val
- assertSameFile ${REF_DIR}/set_existing_option.result ${CHANGES_DIR}/set
-}
-
-test_set_existing_option_multiline()
-{
- cp ${REF_DIR}/set_existing_option.data ${CONFIG_DIR}/set
- ${UCI} set set.section.opt="Hello,\'
-World\""
- assertSameFile ${REF_DIR}/set_existing_option_multiline.result ${CHANGES_DIR}/set
-}
+++ /dev/null
-test_add_section()
-{
- touch ${CONFIG_DIR}/add
- section_name=$(${UCI} add add type)
- assertNotNull "uci add does not return a section name." $section_name
- sed 's/section/'$section_name'/' ${REF_DIR}/add_section.result > ${TMP_DIR}/add_section.result
- assertSameFile ${TMP_DIR}/add_section.result ${CHANGES_DIR}/add
-}
+++ /dev/null
-test_get_parsing()
-{
- cp ${REF_DIR}/show_parsing.data ${CONFIG_DIR}/test
-
- assertFailWithNoReturn "${UCI_Q} show test."
- assertFailWithNoReturn "${UCI_Q} show test.section."
- assertFailWithNoReturn "${UCI_Q} show test.section.opt."
- assertFailWithNoReturn "${UCI_Q} show test.section.opt.val."
- assertFailWithNoReturn "${UCI_Q} show test.section.opt.val.qsdf.qsd"
- assertFailWithNoReturn "${UCI_Q} show test.section.opt.valqsqsd"
- assertFailWithNoReturn "${UCI_Q} show test.nilsection"
- assertFailWithNoReturn "${UCI_Q} show test.nilsection.nilopt"
- assertFailWithNoReturn "${UCI_Q} show test.section.nilopt"
-}
-
-prepare_get_parsing_multiline() {
- cp ${REF_DIR}/show_parsing_multiline.data ${CONFIG_DIR}/sockd
-}
-
-test_get_parsing_multiline_package()
-{
- prepare_get_parsing_multiline
-
- value=$(${UCI_Q} show sockd)
- value_ref=$(cat ${REF_DIR}/show_parsing_multiline_package.result)
- assertEquals "$value_ref" "$value"
-}
-
-test_get_parsing_multiline_section()
-{
- prepare_get_parsing_multiline
-
- value=$(${UCI_Q} show sockd.instance0)
- value_ref=$(cat ${REF_DIR}/show_parsing_multiline_section.result)
- assertEquals "$value_ref" "$value"
-}
-
-test_get_parsing_multiline_option()
-{
- prepare_get_parsing_multiline
-
- value=$(${UCI_Q} show sockd.instance0.extra_config)
- value_ref=$(cat ${REF_DIR}/show_parsing_multiline_option.result)
- assertEquals "$value_ref" "$value"
-}
+++ /dev/null
-test_batch_set()
-{
- touch ${CONFIG_DIR}/batch_set
-
- ${UCI} batch <<EOF
-set batch_set.SEC0='section'
-set batch_set.SEC0.option0='value0'
-set batch_set.SEC0.option1='"Hello,
-'" World\""
-set batch_set.SEC1='section'
-set batch_set.SEC1.option0="value1"
-
-EOF
- ${UCI} commit
- assertSameFile "${REF_DIR}/batch_set.result" "${CONFIG_DIR}/batch_set"
-}
-
-test_batch_comments()
-{
- touch ${CONFIG_DIR}/batch_comments
-
- ${UCI} batch <<EOF
-# first line comment
-set batch_comments.SEC0='section'
-set batch_comments.SEC0.option0='value0'
-
-# two consecutive blank lines
-# two consecutive blank lines
-
-
-set batch_comments.SEC0.option1='"Hello,
-'" World\""
-set batch_comments.SEC1='section'
-set batch_comments.SEC1.option0="value1"
-
- # comment line starts with spaces.
-
-commit
-# last line comment
-EOF
-
- assertSameFile "${REF_DIR}/batch_comments.result" "${CONFIG_DIR}/batch_comments"
-}
+++ /dev/null
-revert_test_prepare() {
- touch ${CONFIG_DIR}/revert
- ${UCI} set revert.SEC0=section
- ${UCI} set revert.SEC0.option0=value0
- ${UCI} set revert.SEC0.option1='"Hello,
-'" World\""
-}
-
-test_revert_section()
-{
- revert_test_prepare
- ${UCI} revert revert.SEC0
- assertSameFile "${REF_DIR}/revert_section.result" "$CHANGES_DIR/revert"
-}
-
-test_revert_option()
-{
- revert_test_prepare
- ${UCI} revert revert.SEC0.option0
- assertSameFile "${REF_DIR}/revert_option.result" "$CHANGES_DIR/revert"
-}
-
-test_revert_option_multiline()
-{
- revert_test_prepare
- ${UCI} revert revert.SEC0.option1
- assertSameFile "${REF_DIR}/revert_option_multiline.result" "$CHANGES_DIR/revert"
-}
-
-test_revert_option_long()
-{
- local val="$(head -c 8192 < /dev/zero | tr '\0' 'a')"
- local res
-
- touch ${CONFIG_DIR}/p
-
- ${UCI} set p.s=sec
- ${UCI} set p.s.o="$val"
-
- res="$(${UCI} changes)"
- assertEquals "p.s='sec'
-p.s.o='$val'" "$res"
-
- ${UCI} revert p
- res="$(${UCI} changes)"
- assertEquals "" "$res"
-}
+++ /dev/null
-prepare_list_test() {
- touch ${CONFIG_DIR}/list_test_config
- ${UCI} set list_test_config.SEC0=section
- ${UCI} add_list list_test_config.SEC0.list0=value0
- ${UCI} add_list list_test_config.SEC0.list0='"Hello
-,'" world\""
-}
-test_add_list_config() {
- prepare_list_test
- ${UCI} commit
- assertSameFile "${REF_DIR}/add_list_config.result" "$CONFIG_DIR/list_test_config"
-}
-
-test_add_list_get() {
- # To maintain compatibility with current code, do not quote
- # list values that do not contain blank spaces ("\x20\t\r\n") within it.
- prepare_list_test
- value_list_get=$(${UCI} get list_test_config.SEC0.list0)
- assertEquals "$value_list_get" "value0 '\"Hello
-, world\"'"
-}
-
-test_add_list_show() {
- prepare_list_test
- value_list_show=$(${UCI} show list_test_config)
- value_list_show_ref=$(cat "$REF_DIR/add_list_show.result")
- assertEquals "$value_list_show" "$value_list_show_ref"
-}
-
-test_add_list_changes() {
- prepare_list_test
- value_list_changes=$(${UCI} changes)
- value_list_changes_ref=$(cat "$REF_DIR/add_list_changes.result")
- assertEquals "$value_list_changes" "$value_list_changes_ref"
-}
-
-test_del_list() {
- prepare_list_test
- ${UCI} commit
- ${UCI} del_list list_test_config.SEC0.list0=value0
- ${UCI} commit
- assertSameFile "${REF_DIR}/del_list_config.result" "$CONFIG_DIR/list_test_config"
-}
-
-test_del_list_multiline() {
- prepare_list_test
- ${UCI} commit
- ${UCI} del_list list_test_config.SEC0.list0='"Hello
-,'' world"'
- ${UCI} commit
- assertSameFile "${REF_DIR}/del_list_multiline_config.result" "$CONFIG_DIR/list_test_config"
-}
+++ /dev/null
-test_add_delta() {
- local new_savedir="$TMP_DIR/new_savedir"
- local config_delta="$CONFIG_DIR/delta"
- local cmdoutput
-
- # add normal changes
- touch "$config_delta"
- $UCI set delta.sec0=sectype
- $UCI add_list delta.sec0.li0=0
-
- # save new changes in "$new_savedir"
- mkdir -p "$new_savedir"
- touch "$new_savedir/delta"
- $UCI -P "$new_savedir" set delta.sec0=sectype
- $UCI -P "$new_savedir" add_list delta.sec0.li0=1
-
- assertEquals "delta.sec0='sectype'
-delta.sec0.li0+='0'" "$($UCI changes)"
-
- # check combined changes. Order matters here.
- cmdoutput="$($UCI -P "$new_savedir" changes)"
- assertTrue "$?"
- assertEquals "delta.sec0='sectype'
-delta.sec0.li0+='0'
-delta.sec0='sectype'
-delta.sec0.li0+='1'" "$cmdoutput"
-
- # check combined export. Order matters here.
- cmdoutput="$($UCI -P "$new_savedir" export)"
- assertTrue "$?"
- assertEquals "$(cat $REF_DIR/cli.options.delta.export.result)" "$cmdoutput"
-
- # check CLI_FLAG_NOCOMMIT with -P option.
- $UCI -P "$new_savedir" commit
- assertTrue "$?"
- assertEquals "" "$(cat $config_delta)"
-
- # check normal commit.
- $UCI -p "$new_savedir" commit
- assertTrue "$?"
- assertSameFile "$REF_DIR/cli.options.delta.commit.result" "$config_delta"
-
- rm -rf "$new_savedir"
- rm -f "$config_delta"
-}
-
+++ /dev/null
-test_changes_tailing_parts()
-{
- local c val
- for c in + '' @ ^ '|' '~'; do
- touch ${CONFIG_DIR}/network
- cat >${CHANGES_DIR}/network <<-EOF
- ${c}network.foo bar
- ${c}network.foo bar=baz
- ${c}network.foo.bar baz
- ${c}network.foo.bar baz=bazz
- EOF
- val=$(${UCI} changes)
- assertNotSegFault "$?"
- assertNull "$val"
- done
-}
-
-test_changes_missing_value()
-{
- local c val
- for c in + '' @ ^ '|' '~'; do
- touch ${CONFIG_DIR}/network
- mkdir -p ${CHANGES_DIR}
- cat >${CHANGES_DIR}/network <<-EOF
- ${c}network.foo
- ${c}network.foo.bar
- EOF
- val=$(${UCI} changes)
- assertNotSegFault "$?"
- assertNull "$val"
- done
-}
+++ /dev/null
-#!/bin/sh
-
-TESTS_DIR="./tests"
-CONFIG_DIR=${TESTS_DIR}"/config"
-CHANGES_DIR="/tmp/.uci"
-TMP_DIR=${TESTS_DIR}"/tmp"
-FULL_SUITE=${TESTS_DIR}"/full_suite.sh"
-
-UCI_BIN="../uci"
-[ -x $UCI_BIN ] || {
- echo "uci is not present." >&2
- return 1
-}
-UCI="${UCI_BIN} -c ${CONFIG_DIR} -p ${CHANGES_DIR}"
-UCI_Q="${UCI_BIN} -c ${CONFIG_DIR} -p ${CHANGES_DIR} -q"
-
-REF_DIR="./references"
-SCRIPTS_DIR="./tests.d"
-DO_TEST="./shunit2/shunit2"
-
-rm -rf ${TESTS_DIR}
-mkdir -p ${TESTS_DIR}
-
-cat << 'EOF' > ${FULL_SUITE}
-setUp() {
- mkdir -p ${CONFIG_DIR} ${CHANGES_DIR} ${TMP_DIR}
-}
-tearDown() {
- rm -rf ${CONFIG_DIR} ${CHANGES_DIR} ${TMP_DIR}
-}
-assertSameFile() {
- local ref=$1
- local test=$2
- diff -qr $ref $test
- assertTrue $? || {
- echo "REF:"
- cat $ref
- echo "----"
- echo "TEST:"
- cat $test
- echo "----"
- }
-}
-assertNotSegFault()
-{
- [ $1 -eq 139 ] && fail "Returned with 139: segmentation fault (SIGSEGV)!!!"
-}
-assertNotIllegal()
-{
- [ $1 -eq 132 ] && fail "Returned with 132: Illegal instruction (SIGILL)!!!"
-}
-assertFailWithNoReturn() {
- local test="$1"
- value=$( $test )
- rv=$?
- assertFalse "'$test' does not fail" $rv
- assertNotSegFault $rv
- assertNotIllegal $rv
- assertNull "'$test' returns '$value'" "$value"
-}
-EOF
-
-for suite in $(ls ${SCRIPTS_DIR}/*)
-do
- cat ${suite} >> ${FULL_SUITE}
-done
-
-echo ". ${DO_TEST}" >> ${FULL_SUITE}
-
-REF_DIR="${REF_DIR}" \
-CONFIG_DIR="${CONFIG_DIR}" \
-CHANGES_DIR="${CHANGES_DIR}" \
-TMP_DIR="${TMP_DIR}" \
-UCI="${UCI}" \
-UCI_Q="${UCI_Q}" \
-/bin/sh ${FULL_SUITE}
-
-rm -rf ${TESTS_DIR}
--- /dev/null
+all:
+ sh ./tests.sh
--- /dev/null
+This test script uses shunit2 :
+http://code.google.com/p/shunit2/
+
+uci-static binary is used during tests.
+
+
+How to add a test
+=================
+
+* Test files are located in './test/tests.d'
+
+* These files contain shell functions beginning with 'test' :
+"
+test_get_option ()
+{
+...
+}
+...
+"
+
+* shunit2 functions can be used in these functions :
+http://shunit2.googlecode.com/svn/trunk/source/2.1/doc/shunit2.html
+
+* Additional environment variables are available :
+ - ${CONFIG_DIR} : uci search path for config files. This directory is
+ reset after each test.
+ - ${CHANGES_DIR} : uci search path for config change files. This directory is
+ reset after each test.
+ - ${TMP_DIR} : path to a directory where can be stored temporary files
+ during tests. This directory is reset after each test.
+ - ${UCI} : uci static binary called with above config and changes
+ directories as parameters.
+ - ${REF_DIR} : path to a directory where can be stored reference files
+ or data.
--- /dev/null
+config 'alias' 'a'
+ option 'interface' 'lan'
+
+config 'alias' 'b'
+ option 'interface' 'lan'
+
+config 'interface' 'lan'
+ option 'proto' 'static'
+ option 'ifname' 'eth0'
+ option 'test' '123'
+ option 'enabled' 'off'
+ option 'ipaddr' '2.3.4.5'
+
+config 'interface' 'wan'
+ option 'proto' 'dhcp'
+ option 'ifname' 'eth1'
+ option 'enabled' 'on'
+ option 'aliases' 'c d'
+
+config 'alias' 'c'
+ option 'interface' 'wan'
+
+config 'alias' 'd'
+ option 'interface' 'wan'
+
--- /dev/null
+list_test_config.SEC0='section'
+list_test_config.SEC0.list0+='value0'
+list_test_config.SEC0.list0+='"Hello
+, world"'
--- /dev/null
+
+config section 'SEC0'
+ list list0 'value0'
+ list list0 '"Hello
+, world"'
+
--- /dev/null
+list_test_config.SEC0=section
+list_test_config.SEC0.list0='value0' '"Hello
+, world"'
--- /dev/null
++add.section='type'
--- /dev/null
+
+config section 'SEC0'
+ option option0 'value0'
+ option option1 '"Hello,
+ World"'
+
+config section 'SEC1'
+ option option0 'value1'
+
--- /dev/null
+
+config section 'SEC0'
+ option option0 'value0'
+ option option1 '"Hello,
+ World"'
+
+config section 'SEC1'
+ option option0 'value1'
+
--- /dev/null
+
+config sectype 'sec0'
+ list li0 '1'
+ list li0 '0'
+
--- /dev/null
+package delta
+
+config sectype 'sec0'
+ list li0 '0'
+ list li0 '1'
--- /dev/null
+
+config section 'SEC0'
+ list list0 '"Hello
+, world"'
+
--- /dev/null
+
+config section 'SEC0'
+ list list0 'value0'
+
--- /dev/null
+
+config 'type' 'section'
+ option 'opt' 'val'
+ list 'list_opt' 'val0'
+ list 'list_opt' 'val1'
+ option mul_line_opt_sq 'line 1
+line 2 \
+line 3'
+ option mul_line_opt_dq "\"Hello\, \
+World.\'
+"
--- /dev/null
+package export
+
+config type 'section'
+ option opt 'val'
+ list list_opt 'val0'
+ list list_opt 'val1'
+ option mul_line_opt_sq 'line 1
+line 2 \
+line 3'
+ option mul_line_opt_dq '"Hello, World.'\''
+'
+
--- /dev/null
+config 'type' 'section'
+ option 'opt' 'val'
--- /dev/null
+config 'type' 'section'
+ # Cannot preserve trailling whitespace with assertEquals.
+ option opt "\"Hello, \
+World.
+\'"
--- /dev/null
+config 'type' 'section'
+ option 'opt' 'val'
+
+config 'unnamed'
+ option 'opt1' 'val1'
--- /dev/null
+package 'import-test'
+
+config 'type' 'section'
+ option 'opt' 'val'
+ list 'list_opt' 'val0'
+ list 'list_opt' 'val1'
+ option mul_line_opt_sq \''line 1
+line 2 \
+line 3'\'
+ option mul_line_opt_dq "\"Hello, \
+World.\'
+"
--- /dev/null
+
+config type 'section'
+ option opt 'val'
+ list list_opt 'val0'
+ list list_opt 'val1'
+ option mul_line_opt_sq ''\''line 1
+line 2 \
+line 3'\'''
+ option mul_line_opt_dq '"Hello, World.'\''
+'
+
--- /dev/null
+revert.SEC0='section'
+revert.SEC0.option1='"Hello,
+ World"'
--- /dev/null
+revert.SEC0='section'
+revert.SEC0.option0='value0'
--- /dev/null
+config 'named' 'section'
+ option 'opt' 'err'
--- /dev/null
+set.section.opt='val'
--- /dev/null
+set.section.opt='Hello,\'\''
+World"'
--- /dev/null
+set.section='named'
--- /dev/null
+config 'named' 'section'
--- /dev/null
+set.section.opt='val'
--- /dev/null
+set.section.opt='Hello,\'\''
+World"'
--- /dev/null
+config 'type' 'section'
+ option 'opt' 'val'
--- /dev/null
+config 'type' 'section'
+ option 'opt' 'val'
--- /dev/null
+config 'type' 'section'
+ option 'opt' 'val'
--- /dev/null
+config main
+ option version 1.4.1
+
+config sockd 'instance0'
+ option enabled 1
+ list internal_network vpn
+ list external_network wan
+
+ option extra_config '
+ user.unprivileged: nobody
+ client pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ session.max: 64
+ log: error
+ }
+
+ socks pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: connect
+ } '
--- /dev/null
+sockd.instance0.extra_config='
+ user.unprivileged: nobody
+ client pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ session.max: 64
+ log: error
+ }
+
+ socks pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: connect
+ } '
--- /dev/null
+sockd.@main[0]=main
+sockd.@main[0].version='1.4.1'
+sockd.instance0=sockd
+sockd.instance0.enabled='1'
+sockd.instance0.internal_network='vpn'
+sockd.instance0.external_network='wan'
+sockd.instance0.extra_config='
+ user.unprivileged: nobody
+ client pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ session.max: 64
+ log: error
+ }
+
+ socks pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: connect
+ } '
--- /dev/null
+sockd.instance0=sockd
+sockd.instance0.enabled='1'
+sockd.instance0.internal_network='vpn'
+sockd.instance0.external_network='wan'
+sockd.instance0.extra_config='
+ user.unprivileged: nobody
+ client pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ session.max: 64
+ log: error
+ }
+
+ socks pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: connect
+ } '
--- /dev/null
+New network section 'lan'
+ type: static
+ ifname: eth0
+ ipaddr: 2.3.4.5
+ test: 123
+ enabled: off
+New alias: a
+New alias: b
+New network section 'wan'
+ type: dhcp
+ ifname: eth1
+ ipaddr: 0.0.0.0
+ test: -1
+ enabled: on
+Configured aliases: c d
--- /dev/null
+New network section 'lan'
+ type: static
+ ifname: eth0
+ ipaddr: 0.0.0.0
+ test: 123
+ enabled: off
+Configured aliases: a b
+New network section 'wan'
+ type: dhcp
+ ifname: eth1
+ ipaddr: 0.0.0.0
+ test: -1
+ enabled: on
+Configured aliases: c d
--- /dev/null
+# $Id: shunit2 189 2008-07-11 11:46:54Z kate.ward@forestent.com $
+# vim:et:ft=sh:sts=2:sw=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.1.4
+# Shell Unit Test Framework
+#
+# http://shunit2.sourceforge.net/
+#
+# written by Kate Ward <kate.ward@forestent.com>
+# released under the LGPL
+#
+# this module implements a xUnit based unit test framework similar to JUnit
+# </s:header>
+#*/
+
+SHUNIT_VERSION='2.1.4'
+
+_shunit_warn() { echo "shunit2:WARN $@" >&2; }
+_shunit_error() { echo "shunit2:ERROR $@" >&2; }
+_shunit_fatal() { echo "shunit2:FATAL $@" >&2; }
+
+SHUNIT_TRUE=0
+SHUNIT_FALSE=1
+SHUNIT_ERROR=2
+
+# specific shell checks
+if [ -n "${ZSH_VERSION:-}" ]; then
+ setopt |grep "^shwordsplit$" >/dev/null
+ if [ $? -ne ${SHUNIT_TRUE} ]; then
+ _shunit_fatal 'zsh shwordsplit option is required for proper operation'
+ exit ${SHUNIT_ERROR}
+ fi
+ if [ -z "${SHUNIT_PARENT:-}" ]; then
+ _shunit_fatal "zsh does not pass \$0 through properly. please declare \
+\"SHUNIT_PARENT=\$0\" before calling shUnit2"
+ exit ${SHUNIT_ERROR}
+ fi
+fi
+
+# shell flags for shunit2:
+# 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 ourself
+shunit_shellFlags_="$-"
+for shunit_shellFlag_ in `echo "${__SHUNIT_SHELL_FLAGS}" |sed 's/\(.\)/\1 /g'`
+do
+ set -${shunit_shellFlag_}
+done
+
+#
+# constants
+#
+
+__SHUNIT_ASSERT_MSG_PREFIX='ASSERT:'
+__SHUNIT_PARENT=${SHUNIT_PARENT:-$0}
+
+# set the constants readonly
+shunit_constants_=`set |grep "^__SHUNIT_" |cut -d= -f1`
+echo "${shunit_constants_}" |grep "^Binary file" >/dev/null
+if [ $? -eq 0 ]; then
+ # deal with binary junk in 'set' output
+ shunit_constants_=`set |grep -a "^__SHUNIT_" |cut -d= -f1`
+fi
+for shunit_const_ in ${shunit_constants_}; do
+ shunit_ro_opts_=''
+ if [ -n "${ZSH_VERSION:-}" ]; then
+ case ${ZSH_VERSION} in
+ [123].*) ;;
+ *) shunit_ro_opts_='-g' ;; # declare readonly constants globally
+ esac
+ fi
+ readonly ${shunit_ro_opts_} ${shunit_const_}
+done
+unset shunit_const_ shunit_constants_ shunit_ro_opts_
+
+# variables
+__shunit_skip=${SHUNIT_FALSE}
+__shunit_suite=''
+
+__shunit_testsPassed=0
+__shunit_testsFailed=0
+__shunit_testsSkipped=0
+__shunit_testsTotal=0
+
+# macros
+_SHUNIT_LINENO_='eval if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && shunit_message_="[$2]"; shift 2; fi'
+
+#-----------------------------------------------------------------------------
+# 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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 2 -o $# -gt 3 ]; then
+ _shunit_error 'assertEquals() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 3 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+ shunit_expected_=$1
+ shunit_actual_=$2
+
+ shunit_return=${SHUNIT_TRUE}
+ if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
+ _shunit_testPassed
+ else
+ failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
+ shunit_return=${SHUNIT_FALSE}
+ fi
+
+ unset shunit_message_ shunit_expected_ shunit_actual_ __shunit_lineno
+ return ${shunit_return}
+}
+_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 1 -o $# -gt 2 ]; then
+ _shunit_error 'assertNull() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 2 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+ if [ $# -eq 2 ]; then
+ assertTrue "${shunit_message_}$1" "[ -z '$2' ]"
+ else
+ assertTrue "[ -z '$1' ]"
+ fi
+}
+_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -gt 2 ]; then # allowing 0 arguments as $1 might actually be null
+ _shunit_error 'assertNotNull() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ if [ $# -eq 2 ]; then
+ assertTrue "$1" "[ -n '$2' ]"
+ else
+ assertTrue "[ -n '${1:-}' ]"
+ fi
+}
+_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 2 -o $# -gt 3 ]; then
+ _shunit_error 'assertSame() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ if [ $# -eq 2 ]; then
+ assertEquals "$1" "$2"
+ else
+ assertEquals "$1" "$2" "$3"
+ fi
+}
+_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 2 -o $# -gt 3 ]; then
+ _shunit_error 'assertNotSame() requires two or three arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 3 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+ shunit_unexpected_=$1
+ shunit_actual_=$2
+
+ shunit_return=${SHUNIT_TRUE}
+ if [ "${shunit_unexpected_}" != "${shunit_actual_}" ]; then
+ _shunit_testPassed
+ else
+ failSame "${shunit_message_}" "$@"
+ shunit_return=${SHUNIT_FALSE}
+ fi
+
+ unset shunit_message_ shunit_unexpected_ shunit_actual_
+ return ${shunit_return}
+}
+_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -gt 2 ]; then
+ _shunit_error 'assertTrue() takes one two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 2 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+ shunit_condition_=$1
+
+ # see if condition is an integer, i.e. a return value
+ shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
+ shunit_return=${SHUNIT_TRUE}
+ if [ -z "${shunit_condition_}" ]; then
+ # null condition
+ shunit_return=${SHUNIT_FALSE}
+ elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then
+ # possible return value. treating 0 as true, and non-zero as false.
+ [ ${shunit_condition_} -ne 0 ] && shunit_return=${SHUNIT_FALSE}
+ else
+ # (hopefully) a condition
+ ( eval ${shunit_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 "${shunit_message_}"
+ fi
+
+ unset shunit_message_ shunit_condition_ shunit_match_
+ return ${shunit_return}
+}
+_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 1 -o $# -gt 2 ]; then
+ _shunit_error 'assertFalse() quires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 2 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+ shunit_condition_=$1
+
+ # see if condition is an integer, i.e. a return value
+ shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
+ shunit_return=${SHUNIT_TRUE}
+ if [ -z "${shunit_condition_}" ]; then
+ # null condition
+ shunit_return=${SHUNIT_FALSE}
+ elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then
+ # possible return value. treating 0 as true, and non-zero as false.
+ [ ${shunit_condition_} -eq 0 ] && shunit_return=${SHUNIT_FALSE}
+ else
+ # (hopefully) a condition
+ ( eval ${shunit_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 "${shunit_message_}"
+ fi
+
+ unset shunit_message_ shunit_condition_ shunit_match_
+ return ${shunit_return}
+}
+_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"'
+
+#-----------------------------------------------------------------------------
+# 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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -gt 1 ]; then
+ _shunit_error 'fail() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 1 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+
+ _shunit_testFailed "${shunit_message_}"
+
+ unset shunit_message_
+ return ${SHUNIT_FALSE}
+}
+_FAIL_='eval fail --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 2 -o $# -gt 3 ]; then
+ _shunit_error 'failNotEquals() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 3 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+ shunit_unexpected_=$1
+ shunit_actual_=$2
+
+ _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected:<${shunit_unexpected_}> but was:<${shunit_actual_}>"
+
+ unset shunit_message_ shunit_unexpected_ shunit_actual_
+ return ${SHUNIT_FALSE}
+}
+_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 2 -o $# -gt 3 ]; then
+ _shunit_error 'failSame() requires two or three arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ [ -z "${shunit_message_:-}" ] && shunit_message_=''
+ if [ $# -eq 3 ]; then
+ shunit_message_="${shunit_message_}$1"
+ shift
+ fi
+
+ _shunit_testFailed "${shunit_message_:+${shunit_message_} }expected not same"
+
+ unset shunit_message_
+ return ${SHUNIT_FALSE}
+}
+_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"'
+
+#/**
+# <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()
+{
+ ${_SHUNIT_LINENO_}
+ if [ $# -lt 2 -o $# -gt 3 ]; then
+ _shunit_error 'failNotEquals() requires one or two arguments'
+ return ${SHUNIT_ERROR}
+ fi
+ _shunit_shouldSkip && return ${SHUNIT_TRUE}
+
+ if [ $# -eq 2 ]; then
+ failNotEquals "$1" "$2"
+ else
+ failNotEquals "$1" "$2" "$3"
+ fi
+}
+_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"'
+
+#-----------------------------------------------------------------------------
+# skipping functions
+#
+
+#/**
+# <s:function group="skipping">
+# <entry align="right">
+# <emphasis>void</emphasis>
+# </entry>
+# <entry>
+# <funcsynopsis>
+# <funcprototype>
+# <funcdef><function>startSkipping</function></funcdef>
+# <paramdef />
+# </funcprototype>
+# </funcsynopsis>
+# <para>This function forces the remaining assert and fail functions to be
+# "skipped", i.e. they will have no effect. Each function skipped will be
+# recorded so that the total of asserts and fails will not be altered.</para>
+# </entry>
+# </s:function>
+#*/
+startSkipping()
+{
+ __shunit_skip=${SHUNIT_TRUE}
+}
+
+#/**
+# <s:function group="skipping">
+# <entry align="right">
+# <emphasis>void</emphasis>
+# </entry>
+# <entry>
+# <funcsynopsis>
+# <funcprototype>
+# <funcdef><function>endSkipping</function></funcdef>
+# <paramdef />
+# </funcprototype>
+# </funcsynopsis>
+# <para>This function returns calls to the assert and fail functions to their
+# default behavior, i.e. they will be called.</para>
+# </entry>
+# </s:function>
+#*/
+endSkipping()
+{
+ __shunit_skip=${SHUNIT_FALSE}
+}
+
+#/**
+# <s:function group="skipping">
+# <entry align="right">
+# <emphasis>boolean</emphasis>
+# </entry>
+# <entry>
+# <funcsynopsis>
+# <funcprototype>
+# <funcdef><function>isSkipping</function></funcdef>
+# <paramdef />
+# </funcprototype>
+# </funcsynopsis>
+# <para>This function returns the state of skipping.</para>
+# </entry>
+# </s:function>
+#*/
+isSkipping()
+{
+ return ${__shunit_skip}
+}
+
+#-----------------------------------------------------------------------------
+# 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 ;;
+ *)
+ _shunit_warn "unrecognized trap value (${name})"
+ signal=0
+ ;;
+ esac
+
+ # do our work
+ rm -fr "${__shunit_tmpDir}"
+
+ # exit for all non-EXIT signals
+ if [ ${name} != 'EXIT' ]; then
+ _shunit_warn "trapped and now handling the (${name}) signal"
+ _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
+ # disable skipping
+ endSkipping
+
+ # 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_generateReport()
+{
+ _su__awkPercent='{printf("%4d %3.0f%%", $1, $1*100/$2)}'
+ if [ ${__shunit_testsTotal:-0} -gt 0 ]; then
+ _su__passed=`echo ${__shunit_testsPassed} ${__shunit_testsTotal} |\
+ awk "${_su__awkPercent}"`
+ _su__failed=`echo ${__shunit_testsFailed} ${__shunit_testsTotal} |\
+ awk "${_su__awkPercent}"`
+ _su__skipped=`echo ${__shunit_testsSkipped} ${__shunit_testsTotal} |\
+ awk "${_su__awkPercent}"`
+ _su__total=`echo ${__shunit_testsTotal} 100 |\
+ awk '{printf("%4d %3d%%", $1, $2)}'`
+ else
+ _su__passed=`echo 0 0 |awk '{printf("%4d %3d%%", $1, $2)}'`
+ _su__failed=${_su__passed}
+ _su__skipped=${_su__passed}
+ _su__total=${_su__passed}
+ fi
+
+ cat <<EOF
+
+#
+# Test report
+#
+tests passed: ${_su__passed}
+tests failed: ${_su__failed}
+tests skipped: ${_su__skipped}
+tests total: ${_su__total}
+EOF
+
+ unset _su__awkPercent _su__passed _su__failed _su__skipped _su__total
+}
+
+# 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' ]; then
+ _su__random=`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
+ exit 1
+ }
+
+ 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_shouldSkip()
+{
+ [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}
+ _shunit_testSkipped
+}
+
+_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
+}
+
+_shunit_testSkipped()
+{
+ __shunit_testsSkipped=`expr ${__shunit_testsSkipped} + 1`
+ __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
+}
+
+#------------------------------------------------------------------------------
+# main
+#
+
+# create a temporary storage location
+__shunit_tmpDir=`_shunit_mktempDir`
+
+# 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)
+oneTimeSetUp
+
+# execute the suite function defined in the parent test script
+# deprecated as of 2.1.0
+suite
+
+# if no suite function was defined, dynamically build a list of functions
+if [ -z "${__shunit_suite}" ]; then
+ shunit_funcs_=`grep "^[ \t]*test[A-Za-z0-9_]* *()" ${__SHUNIT_PARENT} \
+ |sed 's/[^A-Za-z0-9_]//g'`
+ for shunit_func_ in ${shunit_funcs_}; do
+ suite_addTest ${shunit_func_}
+ done
+fi
+unset shunit_func_ shunit_funcs_
+
+# 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_shellFlags_} |grep ${shunit_shellFlag_} >/dev/null \
+ || set +${shunit_shellFlag_}
+done
+unset shunit_shellFlag_ shunit_shellFlags_
+
+[ ${__shunit_testsFailed} -eq 0 ] || exit 1
+
+#/**
+# </s:shelldoc>
+#*/
--- /dev/null
+test_import ()
+{
+ ${UCI} import < ${REF_DIR}/import.data
+ assertSameFile ${REF_DIR}/import.result ${CONFIG_DIR}/import-test
+}
--- /dev/null
+test_export ()
+{
+ cp ${REF_DIR}/export.data ${CONFIG_DIR}/export
+
+ ${UCI_Q} export nilpackage
+ assertFalse $?
+
+ ${UCI_Q} export export 1>/dev/null 2>&1
+ assertTrue $?
+
+ ${UCI} export > ${TMP_DIR}/export.result
+ assertTrue $?
+ assertSameFile ${REF_DIR}/export.result ${TMP_DIR}/export.result
+}
--- /dev/null
+test_get_parsing()
+{
+ cp ${REF_DIR}/get_parsing.data ${CONFIG_DIR}/test
+
+ assertFailWithNoReturn "${UCI_Q} get test."
+ assertFailWithNoReturn "${UCI_Q} get test.section."
+ assertFailWithNoReturn "${UCI_Q} get test.section.opt."
+ assertFailWithNoReturn "${UCI_Q} get test.section.opt.val."
+ assertFailWithNoReturn "${UCI_Q} get test.section.opt.val.qsdf.qsd"
+ assertFailWithNoReturn "${UCI_Q} get test.section.opt.valqsqsd"
+}
+
+test_get_section_index_parsing()
+{
+ cp ${REF_DIR}/get_parsing.data ${CONFIG_DIR}/test
+
+ assertFailWithNoReturn "${UCI_Q} get test.@"
+ assertFailWithNoReturn "${UCI_Q} get test.@zer."
+ assertFailWithNoReturn "${UCI_Q} get test.@."
+ assertFailWithNoReturn "${UCI_Q} get test.@zer[1]"
+ assertFailWithNoReturn "${UCI_Q} get test.@.opt"
+ assertFailWithNoReturn "${UCI_Q} get test.@[28]"
+ assertFailWithNoReturn "${UCI_Q} get test.@[1]."
+ assertFailWithNoReturn "${UCI_Q} get test.@[1].val."
+}
+
+test_get_option()
+{
+ cp ${REF_DIR}/get.data ${CONFIG_DIR}/test
+ value=$($UCI get test.section.opt)
+ assertEquals 'val' "$value"
+}
+
+test_get_option_multiline()
+{
+ cp ${REF_DIR}/get_multiline.data ${CONFIG_DIR}/test
+ value="$($UCI get test.section.opt)"
+ assertEquals '"Hello, World.
+'\''' "$value"
+}
+
+test_get_section()
+{
+ cp ${REF_DIR}/get.data ${CONFIG_DIR}/test
+ type=$($UCI get test.section)
+ assertEquals 'type' "$type"
+}
--- /dev/null
+test_set_parsing()
+{
+ cp ${REF_DIR}/set_parsing.data ${CONFIG_DIR}/test
+
+ assertFailWithNoReturn "${UCI_Q} set test.=val"
+ assertFailWithNoReturn "${UCI_Q} set test.section.=val"
+ assertFailWithNoReturn "${UCI_Q} set test.section.opt.=val"
+ assertFailWithNoReturn "${UCI_Q} set test.section.opt.zflk=val"
+}
+
+test_set_named_section()
+{
+ touch ${CONFIG_DIR}/set
+ ${UCI} set set.section=named
+ assertSameFile ${REF_DIR}/set_named_section.result ${CHANGES_DIR}/set
+}
+
+test_set_nonexisting_option()
+{
+ cp ${REF_DIR}/set_nonexisting_option.data ${CONFIG_DIR}/set
+ ${UCI} set set.section.opt=val
+ assertSameFile ${REF_DIR}/set_nonexisting_option.result ${CHANGES_DIR}/set
+}
+
+test_set_nonexisting_option_multiline()
+{
+ cp ${REF_DIR}/set_nonexisting_option.data ${CONFIG_DIR}/set
+ ${UCI} set set.section.opt="Hello,\'
+World\""
+ assertSameFile ${REF_DIR}/set_nonexisting_option_multiline.result ${CHANGES_DIR}/set
+}
+
+test_set_existing_option()
+{
+ cp ${REF_DIR}/set_existing_option.data ${CONFIG_DIR}/set
+ ${UCI} set set.section.opt=val
+ assertSameFile ${REF_DIR}/set_existing_option.result ${CHANGES_DIR}/set
+}
+
+test_set_existing_option_multiline()
+{
+ cp ${REF_DIR}/set_existing_option.data ${CONFIG_DIR}/set
+ ${UCI} set set.section.opt="Hello,\'
+World\""
+ assertSameFile ${REF_DIR}/set_existing_option_multiline.result ${CHANGES_DIR}/set
+}
--- /dev/null
+test_add_section()
+{
+ touch ${CONFIG_DIR}/add
+ section_name=$(${UCI} add add type)
+ assertNotNull "uci add does not return a section name." $section_name
+ sed 's/section/'$section_name'/' ${REF_DIR}/add_section.result > ${TMP_DIR}/add_section.result
+ assertSameFile ${TMP_DIR}/add_section.result ${CHANGES_DIR}/add
+}
--- /dev/null
+test_get_parsing()
+{
+ cp ${REF_DIR}/show_parsing.data ${CONFIG_DIR}/test
+
+ assertFailWithNoReturn "${UCI_Q} show test."
+ assertFailWithNoReturn "${UCI_Q} show test.section."
+ assertFailWithNoReturn "${UCI_Q} show test.section.opt."
+ assertFailWithNoReturn "${UCI_Q} show test.section.opt.val."
+ assertFailWithNoReturn "${UCI_Q} show test.section.opt.val.qsdf.qsd"
+ assertFailWithNoReturn "${UCI_Q} show test.section.opt.valqsqsd"
+ assertFailWithNoReturn "${UCI_Q} show test.nilsection"
+ assertFailWithNoReturn "${UCI_Q} show test.nilsection.nilopt"
+ assertFailWithNoReturn "${UCI_Q} show test.section.nilopt"
+}
+
+prepare_get_parsing_multiline() {
+ cp ${REF_DIR}/show_parsing_multiline.data ${CONFIG_DIR}/sockd
+}
+
+test_get_parsing_multiline_package()
+{
+ prepare_get_parsing_multiline
+
+ value=$(${UCI_Q} show sockd)
+ value_ref=$(cat ${REF_DIR}/show_parsing_multiline_package.result)
+ assertEquals "$value_ref" "$value"
+}
+
+test_get_parsing_multiline_section()
+{
+ prepare_get_parsing_multiline
+
+ value=$(${UCI_Q} show sockd.instance0)
+ value_ref=$(cat ${REF_DIR}/show_parsing_multiline_section.result)
+ assertEquals "$value_ref" "$value"
+}
+
+test_get_parsing_multiline_option()
+{
+ prepare_get_parsing_multiline
+
+ value=$(${UCI_Q} show sockd.instance0.extra_config)
+ value_ref=$(cat ${REF_DIR}/show_parsing_multiline_option.result)
+ assertEquals "$value_ref" "$value"
+}
--- /dev/null
+test_batch_set()
+{
+ touch ${CONFIG_DIR}/batch_set
+
+ ${UCI} batch <<EOF
+set batch_set.SEC0='section'
+set batch_set.SEC0.option0='value0'
+set batch_set.SEC0.option1='"Hello,
+'" World\""
+set batch_set.SEC1='section'
+set batch_set.SEC1.option0="value1"
+
+EOF
+ ${UCI} commit
+ assertSameFile "${REF_DIR}/batch_set.result" "${CONFIG_DIR}/batch_set"
+}
+
+test_batch_comments()
+{
+ touch ${CONFIG_DIR}/batch_comments
+
+ ${UCI} batch <<EOF
+# first line comment
+set batch_comments.SEC0='section'
+set batch_comments.SEC0.option0='value0'
+
+# two consecutive blank lines
+# two consecutive blank lines
+
+
+set batch_comments.SEC0.option1='"Hello,
+'" World\""
+set batch_comments.SEC1='section'
+set batch_comments.SEC1.option0="value1"
+
+ # comment line starts with spaces.
+
+commit
+# last line comment
+EOF
+
+ assertSameFile "${REF_DIR}/batch_comments.result" "${CONFIG_DIR}/batch_comments"
+}
--- /dev/null
+revert_test_prepare() {
+ touch ${CONFIG_DIR}/revert
+ ${UCI} set revert.SEC0=section
+ ${UCI} set revert.SEC0.option0=value0
+ ${UCI} set revert.SEC0.option1='"Hello,
+'" World\""
+}
+
+test_revert_section()
+{
+ revert_test_prepare
+ ${UCI} revert revert.SEC0
+ assertSameFile "${REF_DIR}/revert_section.result" "$CHANGES_DIR/revert"
+}
+
+test_revert_option()
+{
+ revert_test_prepare
+ ${UCI} revert revert.SEC0.option0
+ assertSameFile "${REF_DIR}/revert_option.result" "$CHANGES_DIR/revert"
+}
+
+test_revert_option_multiline()
+{
+ revert_test_prepare
+ ${UCI} revert revert.SEC0.option1
+ assertSameFile "${REF_DIR}/revert_option_multiline.result" "$CHANGES_DIR/revert"
+}
+
+test_revert_option_long()
+{
+ local val="$(head -c 8192 < /dev/zero | tr '\0' 'a')"
+ local res
+
+ touch ${CONFIG_DIR}/p
+
+ ${UCI} set p.s=sec
+ ${UCI} set p.s.o="$val"
+
+ res="$(${UCI} changes)"
+ assertEquals "p.s='sec'
+p.s.o='$val'" "$res"
+
+ ${UCI} revert p
+ res="$(${UCI} changes)"
+ assertEquals "" "$res"
+}
--- /dev/null
+prepare_list_test() {
+ touch ${CONFIG_DIR}/list_test_config
+ ${UCI} set list_test_config.SEC0=section
+ ${UCI} add_list list_test_config.SEC0.list0=value0
+ ${UCI} add_list list_test_config.SEC0.list0='"Hello
+,'" world\""
+}
+test_add_list_config() {
+ prepare_list_test
+ ${UCI} commit
+ assertSameFile "${REF_DIR}/add_list_config.result" "$CONFIG_DIR/list_test_config"
+}
+
+test_add_list_get() {
+ # To maintain compatibility with current code, do not quote
+ # list values that do not contain blank spaces ("\x20\t\r\n") within it.
+ prepare_list_test
+ value_list_get=$(${UCI} get list_test_config.SEC0.list0)
+ assertEquals "$value_list_get" "value0 '\"Hello
+, world\"'"
+}
+
+test_add_list_show() {
+ prepare_list_test
+ value_list_show=$(${UCI} show list_test_config)
+ value_list_show_ref=$(cat "$REF_DIR/add_list_show.result")
+ assertEquals "$value_list_show" "$value_list_show_ref"
+}
+
+test_add_list_changes() {
+ prepare_list_test
+ value_list_changes=$(${UCI} changes)
+ value_list_changes_ref=$(cat "$REF_DIR/add_list_changes.result")
+ assertEquals "$value_list_changes" "$value_list_changes_ref"
+}
+
+test_del_list() {
+ prepare_list_test
+ ${UCI} commit
+ ${UCI} del_list list_test_config.SEC0.list0=value0
+ ${UCI} commit
+ assertSameFile "${REF_DIR}/del_list_config.result" "$CONFIG_DIR/list_test_config"
+}
+
+test_del_list_multiline() {
+ prepare_list_test
+ ${UCI} commit
+ ${UCI} del_list list_test_config.SEC0.list0='"Hello
+,'' world"'
+ ${UCI} commit
+ assertSameFile "${REF_DIR}/del_list_multiline_config.result" "$CONFIG_DIR/list_test_config"
+}
--- /dev/null
+test_add_delta() {
+ local new_savedir="$TMP_DIR/new_savedir"
+ local config_delta="$CONFIG_DIR/delta"
+ local cmdoutput
+
+ # add normal changes
+ touch "$config_delta"
+ $UCI set delta.sec0=sectype
+ $UCI add_list delta.sec0.li0=0
+
+ # save new changes in "$new_savedir"
+ mkdir -p "$new_savedir"
+ touch "$new_savedir/delta"
+ $UCI -P "$new_savedir" set delta.sec0=sectype
+ $UCI -P "$new_savedir" add_list delta.sec0.li0=1
+
+ assertEquals "delta.sec0='sectype'
+delta.sec0.li0+='0'" "$($UCI changes)"
+
+ # check combined changes. Order matters here.
+ cmdoutput="$($UCI -P "$new_savedir" changes)"
+ assertTrue "$?"
+ assertEquals "delta.sec0='sectype'
+delta.sec0.li0+='0'
+delta.sec0='sectype'
+delta.sec0.li0+='1'" "$cmdoutput"
+
+ # check combined export. Order matters here.
+ cmdoutput="$($UCI -P "$new_savedir" export)"
+ assertTrue "$?"
+ assertEquals "$(cat $REF_DIR/cli.options.delta.export.result)" "$cmdoutput"
+
+ # check CLI_FLAG_NOCOMMIT with -P option.
+ $UCI -P "$new_savedir" commit
+ assertTrue "$?"
+ assertEquals "" "$(cat $config_delta)"
+
+ # check normal commit.
+ $UCI -p "$new_savedir" commit
+ assertTrue "$?"
+ assertSameFile "$REF_DIR/cli.options.delta.commit.result" "$config_delta"
+
+ rm -rf "$new_savedir"
+ rm -f "$config_delta"
+}
+
--- /dev/null
+test_changes_tailing_parts()
+{
+ local c val
+ for c in + '' @ ^ '|' '~'; do
+ touch ${CONFIG_DIR}/network
+ cat >${CHANGES_DIR}/network <<-EOF
+ ${c}network.foo bar
+ ${c}network.foo bar=baz
+ ${c}network.foo.bar baz
+ ${c}network.foo.bar baz=bazz
+ EOF
+ val=$(${UCI} changes)
+ assertNotSegFault "$?"
+ assertNull "$val"
+ done
+}
+
+test_changes_missing_value()
+{
+ local c val
+ for c in + '' @ ^ '|' '~'; do
+ touch ${CONFIG_DIR}/network
+ mkdir -p ${CHANGES_DIR}
+ cat >${CHANGES_DIR}/network <<-EOF
+ ${c}network.foo
+ ${c}network.foo.bar
+ EOF
+ val=$(${UCI} changes)
+ assertNotSegFault "$?"
+ assertNull "$val"
+ done
+}
--- /dev/null
+#!/bin/sh
+
+TESTS_DIR="./tests"
+CONFIG_DIR=${TESTS_DIR}"/config"
+CHANGES_DIR="/tmp/.uci"
+TMP_DIR=${TESTS_DIR}"/tmp"
+FULL_SUITE=${TESTS_DIR}"/full_suite.sh"
+
+UCI_BIN="../uci"
+[ -x $UCI_BIN ] || {
+ echo "uci is not present." >&2
+ return 1
+}
+UCI="${UCI_BIN} -c ${CONFIG_DIR} -p ${CHANGES_DIR}"
+UCI_Q="${UCI_BIN} -c ${CONFIG_DIR} -p ${CHANGES_DIR} -q"
+
+REF_DIR="./references"
+SCRIPTS_DIR="./tests.d"
+DO_TEST="./shunit2/shunit2"
+
+rm -rf ${TESTS_DIR}
+mkdir -p ${TESTS_DIR}
+
+cat << 'EOF' > ${FULL_SUITE}
+setUp() {
+ mkdir -p ${CONFIG_DIR} ${CHANGES_DIR} ${TMP_DIR}
+}
+tearDown() {
+ rm -rf ${CONFIG_DIR} ${CHANGES_DIR} ${TMP_DIR}
+}
+assertSameFile() {
+ local ref=$1
+ local test=$2
+ diff -qr $ref $test
+ assertTrue $? || {
+ echo "REF:"
+ cat $ref
+ echo "----"
+ echo "TEST:"
+ cat $test
+ echo "----"
+ }
+}
+assertNotSegFault()
+{
+ [ $1 -eq 139 ] && fail "Returned with 139: segmentation fault (SIGSEGV)!!!"
+}
+assertNotIllegal()
+{
+ [ $1 -eq 132 ] && fail "Returned with 132: Illegal instruction (SIGILL)!!!"
+}
+assertFailWithNoReturn() {
+ local test="$1"
+ value=$( $test )
+ rv=$?
+ assertFalse "'$test' does not fail" $rv
+ assertNotSegFault $rv
+ assertNotIllegal $rv
+ assertNull "'$test' returns '$value'" "$value"
+}
+EOF
+
+for suite in $(ls ${SCRIPTS_DIR}/*)
+do
+ cat ${suite} >> ${FULL_SUITE}
+done
+
+echo ". ${DO_TEST}" >> ${FULL_SUITE}
+
+REF_DIR="${REF_DIR}" \
+CONFIG_DIR="${CONFIG_DIR}" \
+CHANGES_DIR="${CHANGES_DIR}" \
+TMP_DIR="${TMP_DIR}" \
+UCI="${UCI}" \
+UCI_Q="${UCI_Q}" \
+/bin/sh ${FULL_SUITE}
+
+rm -rf ${TESTS_DIR}