Added unit test framework, and some initial unit tests.
authorAndrej Kacian <ticho@claws-mail.org>
Fri, 31 Aug 2018 11:48:30 +0000 (13:48 +0200)
committerAndrej Kacian <ticho@claws-mail.org>
Fri, 14 Sep 2018 09:28:01 +0000 (11:28 +0200)
99 files changed:
.gitignore
Makefile.am
appdata/Makefile.am
config/Makefile.am
config/test-driver [new file with mode: 0755]
configure.ac
doc/Makefile.am
doc/man/Makefile.am
m4/Makefile.am
manual/Makefile.am
manual/de/Makefile.am
manual/de/dist/Makefile.am
manual/de/dist/html/Makefile.am
manual/de/dist/pdf/Makefile.am
manual/de/dist/ps/Makefile.am
manual/de/dist/txt/Makefile.am
manual/dist/Makefile.am
manual/dist/html/Makefile.am
manual/dist/pdf/Makefile.am
manual/dist/ps/Makefile.am
manual/dist/txt/Makefile.am
manual/dtd/Makefile.am
manual/es/Makefile.am
manual/es/dist/Makefile.am
manual/es/dist/html/Makefile.am
manual/es/dist/pdf/Makefile.am
manual/es/dist/ps/Makefile.am
manual/es/dist/txt/Makefile.am
manual/fr/Makefile.am
manual/fr/dist/Makefile.am
manual/fr/dist/html/Makefile.am
manual/fr/dist/pdf/Makefile.am
manual/fr/dist/ps/Makefile.am
manual/fr/dist/txt/Makefile.am
manual/pl/Makefile.am
manual/pl/dist/Makefile.am
manual/pl/dist/html/Makefile.am
manual/pl/dist/pdf/Makefile.am
manual/pl/dist/ps/Makefile.am
manual/pl/dist/txt/Makefile.am
src/Makefile.am
src/common/Makefile.am
src/common/tests/Makefile.am [new file with mode: 0644]
src/common/tests/codeconv_test.c [new file with mode: 0644]
src/common/tests/data/empty.xml [new file with mode: 0644]
src/common/tests/md5_test.c [new file with mode: 0644]
src/common/tests/mock_prefs_common_get_use_shred.h [new file with mode: 0644]
src/common/tests/pkcs5_pbkdf2_test.c [new file with mode: 0644]
src/common/tests/xml_test.c [new file with mode: 0644]
src/etpan/Makefile.am
src/gtk/Makefile.am
src/plugins/Makefile.am
src/plugins/acpi_notifier/Makefile.am
src/plugins/address_keeper/Makefile.am
src/plugins/archive/Makefile.am
src/plugins/att_remover/Makefile.am
src/plugins/attachwarner/Makefile.am
src/plugins/bogofilter/Makefile.am
src/plugins/bsfilter/Makefile.am
src/plugins/clamd/Makefile.am
src/plugins/clamd/libclamd/Makefile.am
src/plugins/demo/Makefile.am
src/plugins/dillo/Makefile.am
src/plugins/fancy/Makefile.am
src/plugins/fetchinfo/Makefile.am
src/plugins/gdata/Makefile.am
src/plugins/libravatar/Makefile.am
src/plugins/mailmbox/Makefile.am
src/plugins/managesieve/Makefile.am
src/plugins/newmail/Makefile.am
src/plugins/notification/Makefile.am
src/plugins/notification/gtkhotkey/Makefile.am
src/plugins/pdf_viewer/Makefile.am
src/plugins/perl/Makefile.am
src/plugins/perl/tools/Makefile.am
src/plugins/pgpcore/Makefile.am
src/plugins/pgpinline/Makefile.am
src/plugins/pgpmime/Makefile.am
src/plugins/python/Makefile.am
src/plugins/python/examples/Makefile.am
src/plugins/rssyl/Makefile.am
src/plugins/rssyl/libfeed/Makefile.am
src/plugins/rssyl/libfeed/tests/Makefile.am [new file with mode: 0644]
src/plugins/rssyl/libfeed/tests/date_test.c [new file with mode: 0644]
src/plugins/rssyl/libfeed/tests/feed_test.c [new file with mode: 0644]
src/plugins/rssyl/libfeed/tests/mock_procheader_date_parse.h [new file with mode: 0644]
src/plugins/rssyl/strutils.h
src/plugins/rssyl/tests/Makefile.am [new file with mode: 0644]
src/plugins/rssyl/tests/strutils_test.c [new file with mode: 0644]
src/plugins/smime/Makefile.am
src/plugins/spam_report/Makefile.am
src/plugins/spamassassin/Makefile.am
src/plugins/tnef_parse/Makefile.am
src/plugins/vcalendar/Makefile.am
src/tests/Makefile.am [new file with mode: 0644]
src/tests/entity_test.c [new file with mode: 0644]
src/tests/mock_debug_print.h [new file with mode: 0644]
tests.mk [new file with mode: 0644]
tools/Makefile.am

index 0cb7868d02635fcaf14577b9433a911db39d6a16..bebe946b70dff0bb8fff6f73fdf1cfe4db643b29 100644 (file)
@@ -102,6 +102,7 @@ Makefile.in
 /src/matcher_parser_parse.c
 /src/matcher_parser_parse.h
 /src/plugins/notification/gtkhotkey/x11/.dirstamp
+*_test
 /src/quote_fmt_lex.c
 /src/quote_fmt_parse.c
 /src/quote_fmt_parse.h
index 3fdb4aabf4250332b5abc8c37029ad7a8e98517c..cbbe2f2b4e42f96e48ea671f5474f285f73e59aa 100644 (file)
@@ -3,6 +3,10 @@
 # terms of the General Public License version 3 (or later).
 # See COPYING file for license details.
 
+if BUILD_TESTS
+include $(top_srcdir)/tests.mk
+endif
+
 ACLOCAL_AMFLAGS = -I m4
 AUTOMAKE_OPTIONS = dist-bzip2 dist-xz
 
index 15066a274edde91f94b5616bdbf6258835ab9ca9..30e47f547189fe659b19682b8bf9f2833dc05e2f 100644 (file)
@@ -40,3 +40,5 @@ appdata_DATA = $(appdata_in_files:.xml.in=.xml)
 
 EXTRA_DIST = $(appdata_DATA) $(appdata_in_files)
 
+
+.PHONY: test
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d4b3f0a129b8cfde47c6c5ab033a3a9f2e5b39a0 100644 (file)
@@ -0,0 +1,2 @@
+
+.PHONY: test
diff --git a/config/test-driver b/config/test-driver
new file mode 100755 (executable)
index 0000000..0218a01
--- /dev/null
@@ -0,0 +1,148 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2016-01-11.22; # UTC
+
+# Copyright (C) 2011-2017 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--]
+              TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+   *) break;;
+  esac
+  shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file"  = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file"  = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+  usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+  usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='\e[0;31m' # Red.
+  grn='\e[0;32m' # Green.
+  lgn='\e[1;32m' # Light green.
+  blu='\e[1;34m' # Blue.
+  mgn='\e[0;35m' # Magenta.
+  std='\e[m'     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  tweaked_estatus=1
+else
+  tweaked_estatus=$estatus
+fi
+
+case $tweaked_estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report the test outcome and exit status in the logs, so that one can
+# know whether the test passed or failed simply by looking at the '.log'
+# file, without the need of also peaking into the corresponding '.trs'
+# file (automake bug#11814).
+echo "$res $test_name (exit status: $estatus)" >>$log_file
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
+# time-stamp-end: "; # UTC"
+# End:
index 05dc92385e0278c85a300f00c63532b3a676a6ab..c4b3e488a26e20a81dce41672844373cddaa487a 100644 (file)
@@ -292,6 +292,10 @@ AC_ARG_ENABLE(svg,
         [  --disable-svg                   Do not build SVG support],
         [enable_svg=$enableval], [enable_svg=yes])
 
+AC_ARG_ENABLE(tests,
+                               [ --enable-tests                   Build unit tests],
+                               [enable_tests=$enableval], [enable_tests=no])
+
 manualdir='${docdir}/manual'
 AC_ARG_WITH(manualdir,
        [  --with-manualdir=DIR    Manual directory],
@@ -953,6 +957,14 @@ else
 fi
 AM_CONDITIONAL(CLAWS_VALGRIND, test x"$enable_valgrind" = x"yes")
 
+AC_MSG_CHECKING([whether to build unit tests])
+if test x$enable_tests = xyes; then
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+fi
+AM_CONDITIONAL(BUILD_TESTS, test "x$enable_tests" = "xyes")
+
 dnl *************************
 dnl ** section for plugins **
 dnl *************************
@@ -1085,7 +1097,7 @@ AC_ARG_ENABLE(vcalendar-plugin,
 
 dnl disabled by default
 AC_ARG_ENABLE(demo-plugin,
-               [  --enable-demo-plugin         Build demo plugin],
+               [  --enable-demo-plugin            Build demo plugin],
                [enable_demo_plugin=$enableval], [enable_demo_plugin=no])
 
 
@@ -2017,6 +2029,7 @@ src/common/version.h
 src/Makefile
 src/common/Makefile
 src/common/passcrypt.h
+src/common/tests/Makefile
 src/gtk/Makefile
 src/etpan/Makefile
 src/plugins/Makefile
@@ -2049,12 +2062,15 @@ src/plugins/pgpcore/Makefile
 src/plugins/pgpmime/Makefile
 src/plugins/pgpinline/Makefile
 src/plugins/rssyl/Makefile
+src/plugins/rssyl/tests/Makefile
 src/plugins/rssyl/libfeed/Makefile
+src/plugins/rssyl/libfeed/tests/Makefile
 src/plugins/smime/Makefile
 src/plugins/spamassassin/Makefile
 src/plugins/spam_report/Makefile
 src/plugins/tnef_parse/Makefile
 src/plugins/vcalendar/Makefile
+src/tests/Makefile
 doc/Makefile
 doc/man/Makefile
 tools/Makefile
@@ -2108,6 +2124,7 @@ echo "Generic UMPC code  : $enable_generic_umpc"
 echo "SVG support        : $enable_svg"
 echo "Config dir         : $ac_cv_with_config_dir"
 echo "Password crypto    : $pwd_crypto"
+echo "Unit tests         : $enable_tests"
 
 echo "Plugins"
 echo "   Built:"
index 5beeea035731a7850382c2b2f5ad13272c3dd452..a8086178b128c9ba1799ef140367f892b791af46 100644 (file)
@@ -4,3 +4,5 @@
 # See COPYING file for license details.
 
 SUBDIRS = man
+
+.PHONY: test
index 54e06ae0485abc43b7fa116b004e7be607dad867..c2c91a4bd16159ad890ad598340d32f992429c2a 100644 (file)
@@ -7,3 +7,5 @@ man_MANS = \
      claws-mail.1
 
 EXTRA_DIST = $(man_MANS)
+
+.PHONY: test
index b4098652cf70473aadd8f0d9ae49391ff27616cd..be424a808d6a2945539c4938911fae36314318f5 100644 (file)
@@ -14,3 +14,5 @@ EXTRA_DIST = codeset.m4 glibc21.m4 intdiv0.m4 intmax.m4 inttypes.m4 inttypes_h.m
        missing/gdk-pixbuf.m4 \
        missing/gettext.m4 \
        missing/gpgme.m4
+
+.PHONY: test
index 179cd6601d585549a2022cac134a00240b85536d..32f249500828845bbd7c22933c7e54191f1ba508 100644 (file)
@@ -21,3 +21,5 @@ EXTRA_DIST = \
        plugins.xml \
        starting.xml \
        claws-mail-manual.xml
+
+.PHONY: test
index 00f1ca8b1ad37f33cb2f4b8adae9585327c58420..1a605a69ad303144dd2eb74d3f3dc76840035538 100644 (file)
@@ -21,3 +21,5 @@ EXTRA_DIST = \
        plugins.xml \
        starting.xml \
        claws-mail-manual.xml
+
+.PHONY: test
index 9bff2bd3fd0ffcf1acca740e571a7b4eeb3ed88c..c19a2fde76efa4cfee209798f8eb270d732562cf 100644 (file)
@@ -4,3 +4,5 @@
 # See COPYING file for license details.
 
 SUBDIRS=html pdf ps txt
+
+.PHONY: test
index 3560fd418ff51171e613d268bbcc2ab59eccfc2f..9b09880ca3dd4852ed23724cdffe4a612ea625cf 100644 (file)
@@ -31,3 +31,5 @@ maintainer-clean:
        -rm claws-mail-manual.html
        -rm claws-mail-manual.html.raw
 endif
+
+.PHONY: test
index 050a7d9c24452c2cc963c52f311f150e74e3c38d..c5a3b9e775583d59332e6a5610dae16b2f9aab90 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.pdf: \
 maintainer-clean:
        -rm claws-mail-manual.pdf claws-mail-manual.fo claws-mail-manual.xsl
 endif
+
+.PHONY: test
index 96a906967e97b0290b3a6bcca6009d459c78edb6..8c2ca0326b1f755b0679265224a61c155102b691 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.ps: \
 maintainer-clean:
        -rm claws-mail-manual.ps
 endif
+
+.PHONY: test
index 020fbf2735f4f7495d0948b14c9f8c94e295ca33..26017b6ed6fdbf58a89f951d306463b2038eb594 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.txt: \
 maintainer-clean:
        -rm claws-mail-manual.txt
 endif
+
+.PHONY: test
index 9bff2bd3fd0ffcf1acca740e571a7b4eeb3ed88c..c19a2fde76efa4cfee209798f8eb270d732562cf 100644 (file)
@@ -4,3 +4,5 @@
 # See COPYING file for license details.
 
 SUBDIRS=html pdf ps txt
+
+.PHONY: test
index 3f66e1c6c59390e868ed9e57e81d8a7be38483ca..cf1d577eebd15a3a6cc2f5c6696bb98ed96dbc56 100644 (file)
@@ -31,3 +31,5 @@ maintainer-clean:
        -rm claws-mail-manual.html
        -rm claws-mail-manual.html.raw
 endif
+
+.PHONY: test
index 2a78f05fad7c66d3aad9fd140c7de75f59c9206c..10329e28fdd5f7a4f9201a45eb9fece73265d213 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.pdf: \
 maintainer-clean:
        -rm claws-mail-manual.pdf claws-mail-manual.fo claws-mail-manual.xsl
 endif
+
+.PHONY: test
index d4f067c18d97e064af250c8403832b74b26a4f5d..0c82b5762c134c59d07fdf9a7572562f99edf1bb 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.ps: \
 maintainer-clean:
        -rm claws-mail-manual.ps
 endif
+
+.PHONY: test
index 34ddc40d449d3890885a1ad0d8a63f15240bb885..afda9927257a46c957d47bcf155a5900867aa4fa 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.txt: \
 maintainer-clean:
        -rm claws-mail-manual.txt
 endif
+
+.PHONY: test
index 0c134f1fd91da65d33221e7e2fb187c0b7c29f35..024b07fe95fff1dbbdb434d899a4abaa938bacd6 100644 (file)
@@ -5,3 +5,5 @@
 
 EXTRA_DIST= \
        manual.dsl  sdocbook.dtd
+
+.PHONY: test
index 00f1ca8b1ad37f33cb2f4b8adae9585327c58420..1a605a69ad303144dd2eb74d3f3dc76840035538 100644 (file)
@@ -21,3 +21,5 @@ EXTRA_DIST = \
        plugins.xml \
        starting.xml \
        claws-mail-manual.xml
+
+.PHONY: test
index 9bff2bd3fd0ffcf1acca740e571a7b4eeb3ed88c..c19a2fde76efa4cfee209798f8eb270d732562cf 100644 (file)
@@ -4,3 +4,5 @@
 # See COPYING file for license details.
 
 SUBDIRS=html pdf ps txt
+
+.PHONY: test
index 155d8f981d4d701ada8757dfb2edff521d916edc..05cec3a1bdd7d473fd40420a8452bb2747a61c9b 100644 (file)
@@ -31,3 +31,5 @@ maintainer-clean:
        -rm claws-mail-manual.html
        -rm claws-mail-manual.html.raw
 endif
+
+.PHONY: test
index 4382322cbc0b4298eae7cb0705b169b8fc9fb397..ac779fb25935b775781a23766aaf67b67db28322 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.pdf: \
 maintainer-clean:
        -rm claws-mail-manual.pdf claws-mail-manual.fo claws-mail-manual.xsl
 endif
+
+.PHONY: test
index 7b26017051d47c25453156e2a8064003f2e4e8e9..fa3e9367bd2812ba202f58b1a9b0b5d1a0cf81cc 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.ps: \
 maintainer-clean:
        -rm claws-mail-manual.ps
 endif
+
+.PHONY: test
index d3c7b61f15210b25d39f03dae033e40269a2c900..8ced198138e9316b607568c06756f0f3293f561f 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.txt: \
 maintainer-clean:
        -rm claws-mail-manual.txt
 endif
+
+.PHONY: test
index 00f1ca8b1ad37f33cb2f4b8adae9585327c58420..1a605a69ad303144dd2eb74d3f3dc76840035538 100644 (file)
@@ -21,3 +21,5 @@ EXTRA_DIST = \
        plugins.xml \
        starting.xml \
        claws-mail-manual.xml
+
+.PHONY: test
index 9bff2bd3fd0ffcf1acca740e571a7b4eeb3ed88c..c19a2fde76efa4cfee209798f8eb270d732562cf 100644 (file)
@@ -4,3 +4,5 @@
 # See COPYING file for license details.
 
 SUBDIRS=html pdf ps txt
+
+.PHONY: test
index a44d39d5030ca143cba1ef2ec45cf2f2aa8ce391..0a0498131d10d27b9058cef8f14176fab63c8ac3 100644 (file)
@@ -31,3 +31,5 @@ maintainer-clean:
        -rm claws-mail-manual.html
        -rm claws-mail-manual.html.raw
 endif
+
+.PHONY: test
index b7a8a5359660193d333eaa55dad12cc70e178d41..2c8f1c31d41b538bc23adb61cb978ba391260dba 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.pdf: \
 maintainer-clean:
        -rm claws-mail-manual.pdf claws-mail-manual.fo claws-mail-manual.xsl
 endif
+
+.PHONY: test
index 53f5bdb8e2ae0b60939b113dbc14e896a1f16485..bb9a6da2df606e9236c3ce187874d0551f8f93dd 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.ps: \
 maintainer-clean:
        -rm claws-mail-manual.ps
 endif
+
+.PHONY: test
index 957b1bf520018d1c5fa85e2fce2e4f31a0340546..16476797550b9134fdb3f11be7fda14da4f03fff 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.txt: \
 maintainer-clean:
        -rm claws-mail-manual.txt
 endif
+
+.PHONY: test
index 00f1ca8b1ad37f33cb2f4b8adae9585327c58420..1a605a69ad303144dd2eb74d3f3dc76840035538 100644 (file)
@@ -21,3 +21,5 @@ EXTRA_DIST = \
        plugins.xml \
        starting.xml \
        claws-mail-manual.xml
+
+.PHONY: test
index 9bff2bd3fd0ffcf1acca740e571a7b4eeb3ed88c..c19a2fde76efa4cfee209798f8eb270d732562cf 100644 (file)
@@ -4,3 +4,5 @@
 # See COPYING file for license details.
 
 SUBDIRS=html pdf ps txt
+
+.PHONY: test
index c1f3ef681e975df909a4eb24562cd5e12e979044..680e4a4cd4f6b82e5a8ec074a6332619b8c6343f 100644 (file)
@@ -31,3 +31,5 @@ maintainer-clean:
        -rm claws-mail-manual.html
        -rm claws-mail-manual.html.raw
 endif
+
+.PHONY: test
index 02eec0b932421518bfcfec45d7074b93fb427e2b..a599acec1a2ab61e20f5539328df6f6e10fd1567 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.pdf: \
 maintainer-clean:
        -rm claws-mail-manual.pdf claws-mail-manual.fo claws-mail-manual.xsl
 endif
+
+.PHONY: test
index 48a27df1ad06096e580603df7b78dddbd8f1b01b..64ad9c075fd4a702adbb49ae778a17625d9fd688 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.ps: \
 maintainer-clean:
        -rm claws-mail-manual.ps
 endif
+
+.PHONY: test
index 31c051d3ba122a329b509dd63717c482100298e8..17f970fdcab573b17eb47c04ffcc54eaf10020bd 100644 (file)
@@ -27,3 +27,5 @@ claws-mail-manual.txt: \
 maintainer-clean:
        -rm claws-mail-manual.txt
 endif
+
+.PHONY: test
index 30e85a4a2bcbdab170f975b748467670d837ad08..9844f304fe8c39ad4735f432f04f58265b4f3b2d 100644 (file)
@@ -11,7 +11,11 @@ etpan_dir =
 etpan_library = 
 endif
 
-SUBDIRS = common gtk $(etpan_dir) . plugins 
+SUBDIRS = common gtk $(etpan_dir) . plugins
+if BUILD_TESTS
+include $(top_srcdir)/tests.mk
+SUBDIRS += tests
+endif
 
 bin_PROGRAMS = claws-mail
 install-exec-hook:
index 56b6cdb088d9519b007b6574686c74af9d23621b..5c4f249573f42fa8a924a1c5ec414800fcc252c9 100644 (file)
@@ -3,6 +3,11 @@
 # terms of the General Public License version 3 (or later).
 # See COPYING file for license details.
 
+if BUILD_TESTS
+include $(top_srcdir)/tests.mk
+SUBDIRS = . tests
+endif
+
 PLUGINDIR = $(pkglibdir)/plugins/
 DESKTOPFILEPATH=$(datadir)/applications/claws-mail.desktop
 
@@ -98,4 +103,3 @@ libclawscommon_la_LIBADD = \
 
 EXTRA_DIST = \
        version.h.in
-
diff --git a/src/common/tests/Makefile.am b/src/common/tests/Makefile.am
new file mode 100644 (file)
index 0000000..7b18f88
--- /dev/null
@@ -0,0 +1,31 @@
+include $(top_srcdir)/tests.mk
+
+common_ldadd = \
+       $(GLIB_LIBS)
+
+AM_CPPFLAGS = \
+       $(GLIB_CFLAGS) \
+       -DLOCALEDIR=\""$(localedir)"\" \
+       -DPLUGINDIR=\"$(PLUGINDIR)\" \
+       -I$(top_srcdir)/src \
+       -I..
+
+TEST_PROGS += xml_test
+xml_test_SOURCES = xml_test.c
+xml_test_LDADD = $(common_ldadd) ../xml.o ../stringtable.o ../utils.o ../codeconv.o ../quoted-printable.o ../unmime.o
+
+TEST_PROGS += codeconv_test
+codeconv_test_SOURCES = codeconv_test.c
+codeconv_test_LDADD = $(common_ldadd) ../codeconv.o ../utils.o ../quoted-printable.o ../unmime.o
+
+TEST_PROGS += md5_test
+md5_test_SOURCES = md5_test.c
+md5_test_LDADD = $(common_ldadd) ../md5.o
+
+TEST_PROGS += pkcs5_pbkdf2_test
+pkcs5_pbkdf2_test_SOURCES = pkcs5_pbkdf2_test.c
+pkcs5_pbkdf2_test_LDADD = $(common_ldadd) ../pkcs5_pbkdf2.o
+
+noinst_PROGRAMS = $(TEST_PROGS)
+
+.PHONY: test
diff --git a/src/common/tests/codeconv_test.c b/src/common/tests/codeconv_test.c
new file mode 100644 (file)
index 0000000..3b93eae
--- /dev/null
@@ -0,0 +1,101 @@
+#include <glib.h>
+
+#include "codeconv.h"
+
+#include "mock_prefs_common_get_use_shred.h"
+
+struct td {
+       gchar *pre; /* Input string */
+       gchar *post; /* Expected output */
+};
+
+struct td from_utf8_empty = { "", "" };
+/* TODO: more tests */
+
+struct td to_utf8_empty = { "", "" };
+/* TODO: more tests */
+
+static void
+test_filename_from_utf8_null()
+{
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               gchar *out;
+
+               out = conv_filename_from_utf8(NULL);
+               g_assert_null(out);
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_stdout("*Condition*failed*");
+       g_test_trap_assert_passed();
+}
+
+static void
+test_filename_from_utf8(gconstpointer user_data)
+{
+       struct td *data = (struct td *)user_data;
+
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               gchar *out;
+
+               out = conv_filename_from_utf8(data->pre);
+               g_assert_cmpstr(out, ==, data->post);
+
+               g_free(out);
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_passed();
+}
+
+static void
+test_filename_to_utf8(gconstpointer user_data)
+{
+       struct td *data = (struct td *)user_data;
+
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               gchar *out;
+
+               out = conv_filename_to_utf8(data->pre);
+               g_assert_cmpstr(out, ==, data->post);
+
+               g_free(out);
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_passed();
+}
+
+int
+main(int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/common/codeconv/filename_from_utf8/null",
+                       test_filename_from_utf8_null);
+       g_test_add_data_func("/common/codeconv/filename_from_utf8/empty",
+                       &from_utf8_empty,
+                       test_filename_from_utf8);
+
+       g_test_add_func("/common/codeconv/filename_to_utf8/null",
+                       test_filename_from_utf8_null);
+       g_test_add_data_func("/common/codeconv/filename_to_utf8/empty",
+                       &to_utf8_empty,
+                       test_filename_to_utf8);
+
+       /* TODO: more tests */
+
+       return g_test_run();
+}
diff --git a/src/common/tests/data/empty.xml b/src/common/tests/data/empty.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/common/tests/md5_test.c b/src/common/tests/md5_test.c
new file mode 100644 (file)
index 0000000..e78d118
--- /dev/null
@@ -0,0 +1,256 @@
+#include <glib.h>
+
+#include <common/md5.h>
+
+struct td_digest {
+       gchar *input;
+       gchar *expected_output;
+};
+
+struct td_digest td_rfc1321_1 = { "", "d41d8cd98f00b204e9800998ecf8427e" };
+struct td_digest td_rfc1321_2 = { "a", "0cc175b9c0f1b6a831c399e269772661" };
+struct td_digest td_rfc1321_3 = { "abc", "900150983cd24fb0d6963f7d28e17f72" };
+struct td_digest td_rfc1321_4 = { "message digest", "f96b697d7cb7938d525a2f31aaf161d0" };
+struct td_digest td_rfc1321_5 = { "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b" };
+struct td_digest td_rfc1321_6 = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f" };
+struct td_digest td_rfc1321_7 = { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" };
+
+struct td_hmac {
+       gchar *key;
+       int key_len;
+       gchar *data;
+       int data_len;
+       gchar *expected_output;
+};
+
+struct td_hmac td_hmac_null_key = {
+       NULL, 50,
+       "", 0,
+       ""
+};
+struct td_hmac td_hmac_negative_key_length = {
+       "", -1,
+       "", 0,
+       ""
+};
+struct td_hmac td_hmac_null_data = {
+       "", 0,
+       NULL, 50,
+       ""
+};
+struct td_hmac td_hmac_negative_data_length = {
+       "abc", 3,
+       "", -1,
+       "",
+};
+
+struct td_hmac td_rfc2202_1 = {
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 16,
+       "Hi There", 8,
+       "9294727a3638bb1c13f48ef8158bfc9d"
+};
+struct td_hmac td_rfc2202_2 = {
+       "Jefe", 4,
+       "what do ya want for nothing?", 28,
+       "750c783e6ab0b503eaa86e310a5db738"
+};
+struct td_hmac td_rfc2202_3 = {
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 16,
+       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50,
+       "56be34521d144c88dbb8c733f0e8b3f6"
+};
+struct td_hmac td_rfc2202_4 = {
+       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
+       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", 50,
+       "697eaf0aca3a3aea3a75164746ffaa79"
+};
+struct td_hmac td_rfc2202_5 = {
+       "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 16,
+       "Test With Truncation", 20,
+       "56461ef2342edc00f9bab995690efd4c"
+};
+struct td_hmac td_rfc2202_6 = {
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80,
+       "Test Using Larger Than Block-Size Key - Hash Key First", 54,
+       "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"
+};
+struct td_hmac td_rfc2202_7 = {
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80,
+       "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
+       "6f630fad67cda0ee1fb1f562db3aa53e"
+};
+
+static void
+test_md5_hex_digest_null_input(void)
+{
+       char outbuf[33];
+
+       outbuf[0] = '\0';
+
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               md5_hex_digest(outbuf, NULL);
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_failed();
+       g_test_trap_assert_stderr("*CRITICAL*md5_hex_digest: assertion*failed*");
+       g_assert_cmpint(outbuf[0], ==, '\0');
+}
+
+static void
+test_md5_hex_digest_null_output(void)
+{
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               md5_hex_digest(NULL, "");
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_failed();
+       g_test_trap_assert_stderr("*CRITICAL*md5_hex_digest: assertion*failed*");
+}
+
+static void
+test_md5_hex_digest(gconstpointer user_data)
+{
+       char outbuf[33];
+       struct td_digest *data = (struct td_digest *)user_data;
+
+       md5_hex_digest(outbuf, data->input);
+
+       g_assert_cmpint(outbuf[32], ==, '\0');
+       g_assert_cmpstr(outbuf, ==, data->expected_output);
+}
+
+static void
+test_md5_hex_hmac_null_output(void)
+{
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               md5_hex_hmac(NULL, "", 0, "", 0);
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_failed();
+       g_test_trap_assert_stderr("*CRITICAL*md5_hex_hmac: assertion*failed*");
+}
+
+/* We expect all test cases using this function to fail with
+ * failed assertion */
+static void
+test_md5_hex_hmac_fails(gconstpointer user_data)
+{
+       char outbuf[33];
+       struct td_hmac *data = (struct td_hmac *)user_data;
+
+       if (!g_test_undefined())
+               return;
+
+       if (g_test_subprocess()) {
+               md5_hex_hmac(outbuf,
+                               data->data, data->data_len,
+                               data->key, data->key_len);
+               return;
+       }
+
+       g_test_trap_subprocess(NULL, 0, 0);
+       g_test_trap_assert_failed();
+       g_test_trap_assert_stderr("*CRITICAL*md5_hex_hmac: assertion*failed*");
+}
+
+static void
+test_md5_hex_hmac(gconstpointer user_data)
+{
+       char outbuf[33];
+       struct td_hmac *data = (struct td_hmac *)user_data;
+
+       md5_hex_hmac(outbuf,
+                       data->data, data->data_len,
+                       data->key, data->key_len);
+
+       g_assert_cmpint(outbuf[32], ==, '\0');
+       g_assert_cmpstr(outbuf, ==, data->expected_output);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/common/md5/hex_digest/null_input",
+                       test_md5_hex_digest_null_input);
+       g_test_add_func("/common/md5/hex_digest/null_output",
+                       test_md5_hex_digest_null_output);
+
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_1",
+                       &td_rfc1321_1,
+                       test_md5_hex_digest);
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_2",
+                       &td_rfc1321_2,
+                       test_md5_hex_digest);
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_3",
+                       &td_rfc1321_3,
+                       test_md5_hex_digest);
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_4",
+                       &td_rfc1321_4,
+                       test_md5_hex_digest);
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_5",
+                       &td_rfc1321_5,
+                       test_md5_hex_digest);
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_6",
+                       &td_rfc1321_6,
+                       test_md5_hex_digest);
+       g_test_add_data_func("/common/md5/hex_digest/rfc1321_7",
+                       &td_rfc1321_7,
+                       test_md5_hex_digest);
+
+       g_test_add_data_func("/common/md5/hex_hmac/null_key",
+                       &td_hmac_null_key,
+                       test_md5_hex_hmac_fails);
+       g_test_add_data_func("/common/md5/hex_hmac/negative_key_length",
+                       &td_hmac_negative_key_length,
+                       test_md5_hex_hmac_fails);
+       g_test_add_data_func("/common/md5/hex_hmac/null_data",
+                       &td_hmac_null_data,
+                       test_md5_hex_hmac_fails);
+       g_test_add_data_func("/common/md5/hex_hmac/negative_data_length",
+                       &td_hmac_negative_data_length,
+                       test_md5_hex_hmac_fails);
+       g_test_add_func("/common/md5/hex_hmac/null_output",
+                       test_md5_hex_hmac_null_output);
+
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_1",
+                       &td_rfc2202_1,
+                       test_md5_hex_hmac);
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_2",
+                       &td_rfc2202_2,
+                       test_md5_hex_hmac);
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_3",
+                       &td_rfc2202_3,
+                       test_md5_hex_hmac);
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_4",
+                       &td_rfc2202_4,
+                       test_md5_hex_hmac);
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_5",
+                       &td_rfc2202_5,
+                       test_md5_hex_hmac);
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_6",
+                       &td_rfc2202_6,
+                       test_md5_hex_hmac);
+       g_test_add_data_func("/common/md5/hex_hmac/rfc2202_7",
+                       &td_rfc2202_7,
+                       test_md5_hex_hmac);
+
+       return g_test_run();
+}
diff --git a/src/common/tests/mock_prefs_common_get_use_shred.h b/src/common/tests/mock_prefs_common_get_use_shred.h
new file mode 100644 (file)
index 0000000..a216cbd
--- /dev/null
@@ -0,0 +1,5 @@
+gboolean prefs_common_get_use_shred(void)
+{
+       return FALSE;
+}
+
diff --git a/src/common/tests/pkcs5_pbkdf2_test.c b/src/common/tests/pkcs5_pbkdf2_test.c
new file mode 100644 (file)
index 0000000..3f7a451
--- /dev/null
@@ -0,0 +1,121 @@
+#include <glib.h>
+
+#include <common/pkcs5_pbkdf2.h>
+
+struct td {
+       gchar *input;
+       size_t input_length;
+       gchar *salt;
+       size_t salt_length;
+       size_t length;
+       guint rounds;
+       gint expected_return;
+       gchar *expected_output;
+};
+
+/* Test vectors from RFC 6070 */
+struct td td_rfc6070_1 = { "password", 8,
+       "salt", 4,
+       20, 1, 0,
+       "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6" };
+struct td td_rfc6070_2 = { "password", 8,
+       "salt", 4,
+       20, 2, 0,
+       "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57" };
+struct td td_rfc6070_3 = { "password", 8,
+       "salt", 4,
+       20, 4096, 0,
+       "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1" };
+struct td td_rfc6070_4 = { "password", 8,
+       "salt", 4,
+       20, 16777216, 0,
+       "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84" };
+struct td td_rfc6070_5 = { "passwordPASSWORDpassword", 24,
+       "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+       25, 4096, 0,
+       "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38" };
+struct td td_rfc6070_6 = { "pass\0word", 9,
+       "sa\0lt", 5,
+       16, 4096, 0,
+       "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3" };
+
+struct td td_zero_rounds = { "abc", 3, "abc", 3, 3, 0, -1, "" };
+struct td td_zero_output_length = { "abc", 3, "abc", 3, 0, 1, -1, NULL };
+struct td td_null_input = { NULL, 10, "", 10, 10, 100, -1, "" };
+struct td td_null_salt = { "", 10, NULL, 10, 10, 100, -1, "" };
+
+static void
+test_pkcs5_pbkdf2(gconstpointer user_data)
+{
+       struct td *data = (struct td *)user_data;
+       guchar *kd = g_malloc0(data->length);
+       gint ret;
+
+       if (data->rounds > 10000 && !g_test_slow()) {
+               gchar *msg = "Time-intensive test, rerun in slow mode to run it.";
+               g_test_skip(msg);
+               g_test_message(msg);
+               return;
+       }
+
+       if (g_test_verbose()) {
+               g_printerr("input '%s' (%ld)\nsalt '%s' (%ld)\nlength %ld\nrounds %d\nexpected_return %d\n",
+                               data->input, data->input_length,
+                               data->salt, data->salt_length,
+                               data->length,
+                               data->rounds,
+                               data->expected_return);
+       }
+
+       ret = pkcs5_pbkdf2(
+                       data->input,
+                       data->input_length,
+                       data->salt,
+                       data->salt_length,
+                       kd,
+                       data->length,
+                       data->rounds);
+
+       g_assert_cmpint(ret, ==, data->expected_return);
+       g_assert_cmpstr(kd, ==, data->expected_output);
+}
+
+static void
+test_pkcs5_pbkdf2_null_output_buffer(void)
+{
+       gint ret = pkcs5_pbkdf2("abc", 3, "abc", 3, NULL, 10, 1);
+
+       g_assert_cmpint(ret, ==, -1);
+}
+
+int
+main(int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_data_func("/common/pkcs5_pbkdf2/zero_rounds",
+                       &td_zero_rounds, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/zero_output_length",
+                       &td_zero_output_length, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/null_salt",
+                       &td_null_salt, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/null_input",
+                       &td_null_input, test_pkcs5_pbkdf2);
+       g_test_add_func("/common/pkcs5_pbkdf2/null_output_buffer",
+                       test_pkcs5_pbkdf2_null_output_buffer);
+
+       g_test_add_data_func("/common/pkcs5_pbkdf2/rfc6070_1",
+                       &td_rfc6070_1, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/rfc6070_2",
+                       &td_rfc6070_2, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/rfc6070_3",
+                       &td_rfc6070_3, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/rfc6070_4",
+                       &td_rfc6070_4, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/rfc6070_5",
+                       &td_rfc6070_5, test_pkcs5_pbkdf2);
+       g_test_add_data_func("/common/pkcs5_pbkdf2/rfc6070_6",
+                       &td_rfc6070_6, test_pkcs5_pbkdf2);
+
+       return g_test_run();
+}
diff --git a/src/common/tests/xml_test.c b/src/common/tests/xml_test.c
new file mode 100644 (file)
index 0000000..1e58d8d
--- /dev/null
@@ -0,0 +1,39 @@
+#include <glib.h>
+
+#include "xml.h"
+
+#include "mock_prefs_common_get_use_shred.h"
+
+#define DATADIR "data/"
+
+static void
+test_xml_open_file_missing(void)
+{
+       XMLFile *xf = xml_open_file(DATADIR "missing.xml");
+       g_assert_null(xf);
+}
+
+static void
+test_xml_open_file_empty(void)
+{
+       XMLFile *xf = xml_open_file(DATADIR "empty.xml");
+       g_assert_nonnull(xf);
+       g_assert_nonnull(xf->buf);
+       g_assert_nonnull(xf->bufp);
+       g_assert_null(xf->dtd);
+       g_assert_null(xf->encoding);
+       g_assert_null(xf->tag_stack);
+       g_assert_cmpint(xf->level, ==, 0);
+       g_assert_false(xf->is_empty_element);
+}
+
+int
+main(int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/common/xml_open_file_missing", test_xml_open_file_missing);
+       g_test_add_func("/common/xml_open_file_empty", test_xml_open_file_empty);
+
+       return g_test_run();
+}
index 111d8d1694a96070ce8391cff725ce67ad3c7e05..2a6e09386e016e4a096ba5025ebb5186079ab736 100644 (file)
@@ -35,3 +35,5 @@ libclawsetpan_la_LIBADD = \
        $(GTK_LIBS) \
        $(LIBETPAN_LIBS) \
        $(ENCHANT_LIBS)
+
+.PHONY: test
index bee037827ca4df8ac5c81889166fdca5b22a56ff..94985abaff0bce0050576ea9cb22b8e80c2fa845 100644 (file)
@@ -101,3 +101,5 @@ claws-marshal.h: claws-marshal.list
 
 claws-marshal.c: claws-marshal.list
        $(GLIB_GENMARSHAL) $< --body --prefix=claws_marshal > $@
+
+.PHONY: test
index 28abfdb67af336e7c07fee514bd82f427202a2aa..1f889568be1b0bca96ecd2c459457fddbd5508a7 100644 (file)
@@ -3,6 +3,8 @@
 # terms of the General Public License version 3 (or later).
 # See COPYING file for license details.
 
+include $(top_srcdir)/tests.mk
+
 SUBDIRS = \
        acpi_notifier \
        address_keeper \
@@ -34,3 +36,5 @@ SUBDIRS = \
        spam_report \
        tnef_parse \
        vcalendar
+
+.PHONY: test
index 2ae194c97544984659d0d799587f84b6ab8c9e9e..cc794db627cfe944a6b3a145392d07482f791a79 100644 (file)
@@ -26,3 +26,5 @@ acpi_notifier_la_CPPFLAGS = \
        -I$(top_srcdir)/src/gtk \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS)
+
+.PHONY: test
index 4a49ae14663842d239ee7333563f6bed45cdd6dd..2388f77590c6b8cf70aa8dae1102d7addcbaede6 100644 (file)
@@ -78,3 +78,5 @@ address_keeper_la_SOURCES = \
        address_keeper.c address_keeper.h \
        address_keeper_prefs.c address_keeper_prefs.h
 
+
+.PHONY: test
index c3cb0517f74eb76fd66c289880749f4415583041..5ca136d6b499351e7e483cb14c68447ac0cb6952 100644 (file)
@@ -36,3 +36,5 @@ archive_la_CPPFLAGS = \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS) \
        $(LIBARCHIVE_CFLAGS)
+
+.PHONY: test
index 543b5bca38347b1a8b9f62edc608728dab9d6b8b..a0f8b92320210a335f2a35f7ee878bf80f06ea87 100644 (file)
@@ -76,3 +76,5 @@ att_remover_la_CPPFLAGS = \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS)
+
+.PHONY: test
index 146180bbebf562184891e755ea3899a350ce1396..6315e9165ae7bc180af42575728de0ee6131ab18 100644 (file)
@@ -78,3 +78,5 @@ attachwarner_la_SOURCES = \
        attachwarner.c attachwarner.h \
        attachwarner_prefs.c attachwarner_prefs.h
 
+
+.PHONY: test
index acb5f4e6e7dce08abd57b3425303ce2c29359d98..b8b6cdc0b50d7a6fb5af5f754184b46ebc16ab46 100644 (file)
@@ -32,3 +32,5 @@ bogofilter_la_CPPFLAGS = \
        $(ENCHANT_CFLAGS) \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS)
+
+.PHONY: test
index 72bee25959d8979306abf731e18801053872c484..8b5d70b4fe4011c95cb1046adbed2b128de86cc7 100644 (file)
@@ -78,3 +78,5 @@ bsfilter_la_SOURCES = \
        bsfilter.c bsfilter.h \
        bsfilter_gtk.c
 
+
+.PHONY: test
index a66e9928fbe34fcc942f19ad71cbb12eef0a3e85..2e29e491065c2a575707b8088719feb6b9147c44 100644 (file)
@@ -32,3 +32,5 @@ clamd_la_CPPFLAGS = \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS)
+
+.PHONY: test
index a71ac3ee9cbc5a4181eb2fca89f585438ad00c1e..12adb3456763288b5cf4edd907d5a81132f5d23c 100644 (file)
@@ -26,3 +26,5 @@ noinst_HEADERS = clamd-plugin.h
 libclamd_plugin_la_LIBADD = \
        @GLIB_LIBS@ \
        @GTK_LIBS@
+
+.PHONY: test
index 8c2d43ab8470824425e26209b159a3162dc8854d..7593ceb45552a3bb428f3b04ae14d28c6ae499d0 100644 (file)
@@ -29,3 +29,5 @@ demo_la_CPPFLAGS = \
        -I$(top_builddir)/src/common \
        -I$(top_srcdir)/src/common \
        $(GLIB_CFLAGS)
+
+.PHONY: test
index 5c15449cfc9656782ac226d47976e93f05fb7985..9be3c1f916c7b44de20ca0822955ec979b7d9732 100644 (file)
@@ -34,3 +34,5 @@ dillo_la_CPPFLAGS = \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS)
+
+.PHONY: test
index bfd1dd01b430850aeba79f7a146fea9f531cad21..d4368615a5da24d751120cdcb40c75004d241be0 100644 (file)
@@ -85,3 +85,5 @@ fancy_la_CPPFLAGS = \
        $(WEBKIT_CFLAGS) \
        $(LIBSOUP_GNOME_CFLAGS) \
        $(CURL_CFLAGS)
+
+.PHONY: test
index ca84f48add8b0ed56b4102e366658aa51cff6cc2..338fe0ae9fd3db3fb9c331170fd3389ffb1770c6 100644 (file)
@@ -76,3 +76,5 @@ fetchinfo_la_CPPFLAGS = \
        $(GTK_CFLAGS)
 
 EXTRA_DIST = claws.def plugin.def version.rc
+
+.PHONY: test
index 84ba0ee4993916abf4bc5f7c1c838e3ab852fbca..39db98c0cbf00d485f3afcf8159ae846e4b8b9fe 100644 (file)
@@ -31,3 +31,5 @@ gdata_la_CPPFLAGS = \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS) \
        $(GDATA_CFLAGS)
+
+.PHONY: test
index ac0f35c3eadfdbee46ceceedfc479bb4dda95a45..c494b039d2e6bd27bd4e59d1f1bfe17640d158d7 100644 (file)
@@ -84,3 +84,5 @@ libravatar_la_SOURCES = \
        libravatar_missing.c libravatar_missing.h \
        libravatar_federation.c libravatar_federation.h
 
+
+.PHONY: test
index 1eceab50a99c81aa1470a70d70a3fb0e43a34895..dffee3aa32636b36e189ff7231ce870a92d3d238 100644 (file)
@@ -88,3 +88,5 @@ mailmbox_la_CPPFLAGS = \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS)
+
+.PHONY: test
index 8a9da5d81e984a91b9b472170629b233522b39d9..fe4cb7d3191752406431cf3c3bea287e13119db9 100644 (file)
@@ -83,3 +83,5 @@ managesieve_la_SOURCES = \
        sieve_manager.c sieve_manager.h \
        sieve_editor.c sieve_editor.h
 
+
+.PHONY: test
index 286d0b1b28fdc314cb661d5e7a726940a9fafbce..33801fb109b9a85db5bf2ad164e16624bed42711 100644 (file)
@@ -22,3 +22,5 @@ newmail_la_CPPFLAGS = \
        -I$(top_srcdir)/src/gtk \
         $(GLIB_CFLAGS) \
        $(GTK_CFLAGS)
+
+.PHONY: test
index 35c2f1ccc585a84b07431d870639c9a5c4b6ba62..9d29d32759359b8495882fd16f38d0c3912acb6a 100644 (file)
@@ -109,3 +109,5 @@ notification_la_CPPFLAGS = \
 
 clean-local:
        rm -f libclaws.a
+
+.PHONY: test
index 96181d1345b7e357a35661d63aa3af9d1dbf923d..3975852d86a5f65a67a1309ae85c3df915019f25 100644 (file)
@@ -31,3 +31,5 @@ libcmnpgtkhotkey_la_CPPFLAGS = \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS) \
        $(CM_NP_HOTKEY_CFLAGS)
+
+.PHONY: test
index 25cabc5a4df5d6e7ad29a3a8b6fcb8980786222e..c790e9426784c896e68f6347d9abe1b7c74110b6 100644 (file)
@@ -27,3 +27,5 @@ pdf_viewer_la_CPPFLAGS = \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS) \
        $(POPPLER_CFLAGS)
+
+.PHONY: test
index 3df58c3a5df129e1fc3c25d85879f58a0d6a3911..1c7bca78343aee796d528cd2edfe46f095e6a58e 100644 (file)
@@ -34,3 +34,5 @@ perl_la_CPPFLAGS = \
 
 EXTRA_DIST = cm_perl.pod
 
+
+.PHONY: test
index 9744b77ee01cb94bc57fccf0af6277e49f565744..65f12c0a52c80a518b7d4a18ec8986bebe9f71a9 100644 (file)
@@ -30,3 +30,5 @@ distclean-local:
        rm -f $$file; \
        done; \
        fi
+
+.PHONY: test
index 5eb32fbc80ab473d80588c925d517e9581803640..c19ebcfb77374f3fda384838a06ea02138e1d1a3 100644 (file)
@@ -95,3 +95,5 @@ pgpcore_la_CPPFLAGS = \
 clean-local:
        rm -f libclaws.a
 
+
+.PHONY: test
index e4ea69c74ed362f243f56c5151278330e66821bb..01931ea2e1dcb52aee8a6bc7a2c8e22e92244204 100644 (file)
@@ -85,3 +85,5 @@ pgpinline_la_CPPFLAGS = \
 
 clean-local:
        rm -f libclaws.a
+
+.PHONY: test
index 952ce56a5fe197b107846330a5a99fabe22d9e4d..167894fb1d313c7a56c38c8079d3deb327c08a45 100644 (file)
@@ -86,3 +86,5 @@ pgpmime_la_CPPFLAGS = \
 
 clean-local:
        rm -f libclaws.a
+
+.PHONY: test
index fe7592ed4da3d1372370c6e0717901802cb31c68..36ca7c4010afe050509510bfc809cd325a84d29e 100644 (file)
@@ -55,3 +55,5 @@ python_la_CPPFLAGS = \
        -DPYTHON_SHARED_LIB="\"$(PYTHON_SHARED_LIB)\"" \
        -DENABLE_PYTHON \
        -fno-strict-aliasing
+
+.PHONY: test
index 5787a2ca2e9c7f5ba573966e6a2ed81cc4931cbe..cbd3c147b94a483d022d5ff04bd899e3bde6e279 100644 (file)
@@ -13,3 +13,5 @@ EXTRA_DIST = \
        main/Open-Tomboy-Notes \
        main/Print-action-names-to-stdout \
        main/Recusively-mark-messages-as-read
+
+.PHONY: test
index 29209b235bd319e127f4b64f0a5da3586d2dfdda..995624c0947db1a3ffb584173c39d44f5e3f888c 100644 (file)
@@ -4,6 +4,10 @@
 # See COPYING file for license details.
 
 SUBDIRS = libfeed
+if BUILD_TESTS
+include $(top_srcdir)/tests.mk
+SUBDIRS += . tests
+endif
 
 EXTRA_DIST = claws.def plugin.def version.rc
 
index 456e253eca0cba3cef94eff7f70726a4f4d08023..4ba2a1617a97c7b21c205a3c285b8c2be2678d0b 100644 (file)
@@ -1,5 +1,11 @@
 if BUILD_RSSYL_PLUGIN
 noinst_LTLIBRARIES = libfeed.la
+
+if BUILD_TESTS
+include $(top_srcdir)/tests.mk
+SUBDIRS = . tests
+endif
+
 endif
 
 libfeed_la_CPPFLAGS = \
diff --git a/src/plugins/rssyl/libfeed/tests/Makefile.am b/src/plugins/rssyl/libfeed/tests/Makefile.am
new file mode 100644 (file)
index 0000000..67e1f32
--- /dev/null
@@ -0,0 +1,22 @@
+include $(top_srcdir)/tests.mk
+
+common_ldadd = \
+       $(GLIB_LIBS) \
+       $(EXPAT_LIBS) \
+       $(CURL_LIBS)
+
+AM_CPPFLAGS = \
+       $(GLIB_CFLAGS) \
+       -I..
+
+TEST_PROGS += date_test
+date_test_SOURCES = date_test.c
+date_test_LDADD = $(common_ldadd) ../libfeed_la-date.o
+
+TEST_PROGS += feed_test
+feed_test_SOURCES = feed_test.c
+feed_test_LDADD = $(common_ldadd) ../libfeed.la
+
+noinst_PROGRAMS = $(TEST_PROGS)
+
+.PHONY: test
diff --git a/src/plugins/rssyl/libfeed/tests/date_test.c b/src/plugins/rssyl/libfeed/tests/date_test.c
new file mode 100644 (file)
index 0000000..cb08224
--- /dev/null
@@ -0,0 +1,34 @@
+#include <glib.h>
+
+#include "date.h"
+
+
+static void
+test_createRFC822Date (void)
+{
+       gchar *buf;
+       time_t t = 0;
+
+       buf = createRFC822Date(&t);
+       if (g_test_verbose())
+               g_printerr("time_t %ld => '%s'\n", t, buf);
+       g_assert_cmpstr(buf, ==, "Thu,  1 Jan 1970 00:00:00 GMT");
+       g_free(buf);
+
+       t = 1534240471;
+       buf = createRFC822Date(&t);
+       if (g_test_verbose())
+               g_printerr("time_t %ld => '%s'\n", t, buf);
+       g_assert_cmpstr(buf, ==, "Tue, 14 Aug 2018 09:54:31 GMT");
+       g_free(buf);
+}
+
+int
+main (int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/rssyl/libfeed/createRFC822Date", test_createRFC822Date);
+
+       return g_test_run();
+}
diff --git a/src/plugins/rssyl/libfeed/tests/feed_test.c b/src/plugins/rssyl/libfeed/tests/feed_test.c
new file mode 100644 (file)
index 0000000..514d19a
--- /dev/null
@@ -0,0 +1,30 @@
+#include <glib.h>
+
+#include "feed.h"
+
+#include "mock_procheader_date_parse.h"
+
+#define FEED_URL "http://example.com/feed.xml"
+
+static void
+test_Feed_create(void)
+{
+       Feed *feed = feed_new(FEED_URL);
+
+       g_assert_nonnull(feed);
+       g_assert_cmpstr(feed->url, ==, FEED_URL);
+       g_assert_true(feed->is_valid);
+       g_assert_true(feed->ssl_verify_peer);
+
+       feed_free(feed);
+}
+
+int
+main(int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/rssyl/libfeed/Feed_create", test_Feed_create);
+
+       return g_test_run();
+}
diff --git a/src/plugins/rssyl/libfeed/tests/mock_procheader_date_parse.h b/src/plugins/rssyl/libfeed/tests/mock_procheader_date_parse.h
new file mode 100644 (file)
index 0000000..37b2182
--- /dev/null
@@ -0,0 +1,7 @@
+time_t
+procheader_date_parse (gchar *dest,
+               const gchar *src,
+               gint len)
+{
+       return 1;
+}
index 2976e6f9c4e19bafe5cf8399c81b86039d9ee06e..853d118a4bfa627bedd83974f958904322240b51 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __STRUTILS_H
 #define __STRUTILS_H
 
+#include <glib.h>
+
 gchar *rssyl_strreplace(gchar *source, gchar *pattern,
                gchar *replacement);
 
diff --git a/src/plugins/rssyl/tests/Makefile.am b/src/plugins/rssyl/tests/Makefile.am
new file mode 100644 (file)
index 0000000..351000a
--- /dev/null
@@ -0,0 +1,17 @@
+include $(top_srcdir)/tests.mk
+
+common_ldadd = \
+       $(GLIB_LIBS)
+
+AM_CPPFLAGS = \
+       $(GLIB_CFLAGS) \
+       -I.. \
+       -I$(top_srcdir)/src
+
+TEST_PROGS += strutils_test
+strutils_test_SOURCES = strutils_test.c
+strutils_test_LDADD = $(common_ldadd) ../rssyl_la-strutils.o
+
+noinst_PROGRAMS = $(TEST_PROGS)
+
+.PHONY: test
diff --git a/src/plugins/rssyl/tests/strutils_test.c b/src/plugins/rssyl/tests/strutils_test.c
new file mode 100644 (file)
index 0000000..b3c976b
--- /dev/null
@@ -0,0 +1,53 @@
+#include "strutils.h"
+
+/* It's safe to mock this out here, we are interested in
+ * rssyl_strreplace(), which doesn't use the real function. */
+gchar *entity_decode(gchar *str)
+{
+       return g_strdup("mocked_entity_decode");
+}
+
+struct test {
+       gchar *string;
+       gchar *pattern;
+       gchar *replacement;
+       gchar *result;
+};
+
+static void
+test_strreplace(void)
+{
+       gint i;
+       static struct test strings[] = {
+               { "simplestring", "foo", "bar", "simplestring" },
+               { "foobarzot", "foo", "", "barzot" },
+               { NULL, NULL }
+       };
+
+       for (i = 0; strings[i].string != NULL; i++) {
+               gchar *result = rssyl_strreplace(
+                               strings[i].string,
+                               strings[i].pattern,
+                               strings[i].replacement);
+
+               if (g_test_verbose()) {
+                       g_printerr("string '%s', pattern '%s', replacement '%s' => result '%s'\n",
+                                       strings[i].string,
+                                       strings[i].pattern,
+                                       strings[i].replacement,
+                                       result);
+               }
+               g_assert_cmpstr(result, ==, strings[i].result);
+               g_free(result);
+       }
+}
+
+int
+main (int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/rssyl/strreplace", test_strreplace);
+
+       return g_test_run();
+}
index c431c7661354ef1b0ae5b81d14537e7ea2ad0f64..d39423337116bedb1c298d677d2c20aff6532528 100644 (file)
@@ -87,3 +87,5 @@ smime_la_CPPFLAGS = \
 
 clean-local:
        rm -f libclaws.a
+
+.PHONY: test
index 5a077dd0bd2bac529b2dc9ada58ed43005777029..e382b1f3d4e5bdf6f56ec7bea169d0e2fd03544a 100644 (file)
@@ -80,3 +80,5 @@ spamreport_la_CPPFLAGS = \
        $(CURL_CFLAGS) \
        $(GTK_CFLAGS) \
        $(ENCHANT_CFLAGS)
+
+.PHONY: test
index 98e3518e9de1a066625fdbdaacf8aa0cca492f17..7e1eb2a908bb0b9c3810123fb21cd519a683c76d 100644 (file)
@@ -38,3 +38,5 @@ spamassassin_la_CPPFLAGS = \
        $(SPAMASSASSIN_CFLAGS)
 
 EXTRA_DIST = README NOTICE
+
+.PHONY: test
index 3dfe9c8fa3ff68e83c82bf3230c2e4f4f4205426..2ef53a893e94e16da0ba9c23c8946ba0a3e54c7a 100644 (file)
@@ -79,3 +79,5 @@ tnef_parse_la_CPPFLAGS = \
        $(GLIB_CFLAGS) \
        $(GTK_CFLAGS) \
        $(YTNEF_CFLAGS)
+
+.PHONY: test
index c0381e70cc41beb78e9e64e56306225f1131549b..8bceff9e6248f4f4513bcab7fedd0b131d567fe0 100644 (file)
@@ -92,3 +92,5 @@ vcalendar_la_CPPFLAGS = \
 
 clean-local:
        rm -f libclaws.a
+
+.PHONY: test
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
new file mode 100644 (file)
index 0000000..b0a256e
--- /dev/null
@@ -0,0 +1,17 @@
+include $(top_srcdir)/tests.mk
+
+common_ldadd = \
+       $(GLIB_LIBS)
+
+AM_CPPFLAGS = \
+       $(GLIB_CFLAGS) \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/common
+
+TEST_PROGS += entity_test
+entity_test_SOURCES = entity_test.c
+entity_test_LDADD = $(common_ldadd) ../entity.o
+
+noinst_PROGRAMS = $(TEST_PROGS)
+
+.PHONY: test
diff --git a/src/tests/entity_test.c b/src/tests/entity_test.c
new file mode 100644 (file)
index 0000000..86816ea
--- /dev/null
@@ -0,0 +1,40 @@
+#include <glib.h>
+#include "mock_debug_print.h"
+
+#include "entity.h"
+
+static void
+test_entity(void)
+{
+       gchar *result;
+
+       result = entity_decode(NULL);
+       g_assert_null(result);
+
+       result = entity_decode("foo");
+       g_assert_null(result);
+
+       result = entity_decode("&Aacute;");
+       g_assert_nonnull(result);
+       if (g_test_verbose())
+               g_printerr("result '%s'\n", result);
+       g_assert_cmpstr(result, ==, "Á");
+       g_free(result);
+
+       result = entity_decode("&#123;");
+       g_assert_nonnull(result);
+       if (g_test_verbose())
+               g_printerr("result '%s'\n", result);
+       g_assert_cmpstr(result, ==, "{");
+       g_free(result);
+}
+
+int
+main(int argc, char *argv[])
+{
+       g_test_init(&argc, &argv, NULL);
+
+       g_test_add_func("/core/entity", test_entity);
+
+       return g_test_run();
+}
diff --git a/src/tests/mock_debug_print.h b/src/tests/mock_debug_print.h
new file mode 100644 (file)
index 0000000..d9e8f69
--- /dev/null
@@ -0,0 +1,2 @@
+void debug_print_real (const gchar *format, ...) { return; }
+const char *debug_srcname(const char *file) { return NULL; }
diff --git a/tests.mk b/tests.mk
new file mode 100644 (file)
index 0000000..aa5a281
--- /dev/null
+++ b/tests.mk
@@ -0,0 +1,67 @@
+GTESTER        = gtester
+GTESTER_REPORT = gtester-report
+
+# initialize variables for unconditional += appending
+TEST_PROGS =
+
+### testing rules
+
+# test: run all tests in cwd and subdirs
+test: test-cwd test-recurse
+# test-cwd: run tests in cwd
+test-cwd: ${TEST_PROGS}
+       @[ -z "$(TEST_PROGS)" ] || { set -e; $(TESTS_ENVIRONMENT) ${GTESTER} --verbose ${TEST_PROGS}; }
+
+# test-recurse: run tests in subdirs
+test-recurse:
+       @ for subdir in $(SUBDIRS) ; do \
+           test "$$subdir" = "." \
+                       -o "$$subdir" = "config" \
+                       -o "$$subdir" = "doc" \
+                       -o "$$subdir" = "manual" \
+                       -o "$$subdir" = "m4" \
+                       -o "$$subdir" = "po" \
+                       -o "$$subdir" = "tools" \
+                       || \
+           ( cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) test ) || exit $? ; \
+         done
+# test-report: run tests in subdirs and generate report
+# perf-report: run tests in subdirs with -m perf and generate report
+# full-report: like test-report: with -m perf and -m slow
+test-report perf-report full-report:   ${TEST_PROGS}
+       @ ignore_logdir=true ; \
+         if test -z "$$GTESTER_LOGDIR" ; then \
+           GTESTER_LOGDIR=`mktemp -d "\`pwd\`/.testlogs-XXXXXX"`; export GTESTER_LOGDIR ; \
+           ignore_logdir=false ; \
+         fi ; \
+         for subdir in $(SUBDIRS) ; do \
+           test "$$subdir" = "." -o "$$subdir" = "po" -o "$$subdir" = "po-properties" || \
+           ( cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $? ; \
+         done ; \
+         test -z "${TEST_PROGS}" || { \
+           case $@ in \
+           test-report) test_options="-k";; \
+           perf-report) test_options="-k -m=perf";; \
+           full-report) test_options="-k -m=perf -m=slow";; \
+           esac ; \
+           set -e; \
+           if test -z "$$GTESTER_LOGDIR" ; then \
+             ${GTESTER} --verbose $$test_options -o test-report.xml ${TEST_PROGS} ; \
+           elif test -n "${TEST_PROGS}" ; then \
+             ${GTESTER} --verbose $$test_options -o `mktemp "$$GTESTER_LOGDIR/log-XXXXXX"` ${TEST_PROGS} ; \
+           fi ; \
+         }; \
+         $$ignore_logdir || { \
+           echo '<?xml version="1.0"?>' > $@.xml ; \
+           echo '<report-collection>'  >> $@.xml ; \
+           for lf in `ls -L "$$GTESTER_LOGDIR"/.` ; do \
+             sed '1,1s/^<?xml\b[^>?]*?>//' <"$$GTESTER_LOGDIR"/"$$lf" >> $@.xml ; \
+           done ; \
+           echo >> $@.xml ; \
+           echo '</report-collection>' >> $@.xml ; \
+           rm -rf "$$GTESTER_LOGDIR"/ ; \
+           ${GTESTER_REPORT} --version 2>/dev/null 1>&2 ; test "$$?" != 0 || ${GTESTER_REPORT} $@.xml >$@.html ; \
+         }
+.PHONY: test test-cwd test-recurse test-report perf-report full-report
+# run make test-cwd as part of make check
+check-local: test-cwd
index 98d8c50fa7f221e5ba2d9e743fcb6dff8f28f7a6..d6c9d211fe9246799f8e96806880594fba7e33c4 100644 (file)
@@ -81,3 +81,5 @@ install-data-local:
        mkdir -p ${pkgdatadir}
        cp ${top_srcdir}/tools/ca-certificates.crt ${pkgdatadir}/
 endif
+
+.PHONY: test