summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Zini <enrico@enricozini.org>2015-09-10 11:23:57 +0200
committerEnrico Zini <enrico@enricozini.org>2015-09-10 11:23:57 +0200
commitc4dce3d9e4331b9f2fdbef5517a054ebf20c7d3d (patch)
tree5521e7e7aa8c10baf406520ca4953019fa57aa80
parentfb21a4dfe2c81640379f64855509fb7613530887 (diff)
downloadlibept-c4dce3d9e4331b9f2fdbef5517a054ebf20c7d3d.tar.gz
Use build-in test framework instead of wibble
-rw-r--r--CMakeLists.txt17
-rwxr-xr-xdebian/rules2
-rw-r--r--ept/CMakeLists.txt47
-rw-r--r--ept/apt/apt-test.cc209
-rw-r--r--ept/apt/apt.test.h193
-rw-r--r--ept/apt/packagerecord-test.cc126
-rw-r--r--ept/apt/packagerecord.test.h138
-rw-r--r--ept/apt/recordparser-test.cc200
-rw-r--r--ept/apt/recordparser.test.h228
-rw-r--r--ept/apt/version-test.cc119
-rw-r--r--ept/apt/version.test.h136
-rw-r--r--ept/axi/axi-test.cc37
-rw-r--r--ept/axi/axi.test.h58
-rw-r--r--ept/debtags/debtags-test.cc167
-rw-r--r--ept/debtags/debtags.test.h197
-rw-r--r--ept/debtags/vocabulary-test.cc195
-rw-r--r--ept/debtags/vocabulary.test.h222
-rw-r--r--ept/test-main.h186
-rw-r--r--ept/test-runner.h63
-rw-r--r--ept/test.h31
-rw-r--r--ept/utils/tests.h6
-rwxr-xr-xrun-check59
22 files changed, 1138 insertions, 1498 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c4b9686..db91197 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.2)
include( FindPkgConfig )
include( FindDoxygen )
-add_custom_target( unit )
+add_custom_target(check COMMAND ${CMAKE_SOURCE_DIR}/run-check ${CMAKE_BINARY_DIR}/ept/test-ept)
set( EPT_VERSION "1.0.14" )
@@ -22,20 +22,7 @@ set( APT_INCLUDES "/usr/include/" CACHE STRING "apt include path" )
set( APT_LINKDIRS "/usr/lib/" CACHE STRING "apt library path" )
set( OPT_FLAGS "-O0 -g" CACHE STRING "optimization level" )
-option( INTERNAL_WIBBLE "use internal copy of wibble" )
-option( RPM "using apt-rpm" )
-
-if( INTERNAL_WIBBLE )
- add_subdirectory( wibble )
- set( WIBBLE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} )
- set( WIBBLE_LIBRARY_DIRS ${wibble_BINARY_DIR} )
- set( WIBBLE_LIBRARIES "wibble" )
- set( WIBBLE_TEST_CMAKE "${wibble_SOURCE_DIR}/test.cmake" )
-else( INTERNAL_WIBBLE )
- pkg_check_modules( WIBBLE REQUIRED "libwibble >= 1.0" )
- find_program( WIBBLE_TEST_GENRUNNER wibble-test-genrunner )
- set( WIBBLE_TEST_CMAKE "${WIBBLE_PREFIX}/share/wibble/test.cmake" )
-endif( INTERNAL_WIBBLE )
+pkg_check_modules( WIBBLE REQUIRED "libwibble >= 1.0" )
add_subdirectory( ept )
add_subdirectory( tools )
diff --git a/debian/rules b/debian/rules
index 37484a8..9c9cd65 100755
--- a/debian/rules
+++ b/debian/rules
@@ -14,7 +14,7 @@ override_dh_fixperms:
override_dh_auto_build:
dh_auto_build
- make -C $(BUILDDIR) unit
+ make -C $(BUILDDIR) check
make -C $(BUILDDIR) doc
override_dh_auto_install:
diff --git a/ept/CMakeLists.txt b/ept/CMakeLists.txt
index 5f27f14..3d2dadd 100644
--- a/ept/CMakeLists.txt
+++ b/ept/CMakeLists.txt
@@ -1,9 +1,11 @@
project( ept )
-include( ${WIBBLE_TEST_CMAKE} )
-file( GLOB src *.cpp debtags/*.cc debtags/maint/*.cc debtags/coll/*.cc
- apt/*.cc axi/*.cc utils/*.cc )
+# Find sources and tests
+file(GLOB src *.cpp debtags/*.cc debtags/maint/*.cc debtags/coll/*.cc apt/*.cc axi/*.cc utils/*.cc)
+file(GLOB tests *-test.cc apt/*-test.cc debtags/*-test.cc axi/*-test.cc)
+list(REMOVE_ITEM src ${tests})
+# Find headers
file( GLOB h_top *.h )
file( GLOB h_apt apt/*.h )
file( GLOB h_debtags debtags/*.h debtags/*.tcc )
@@ -11,10 +13,10 @@ file( GLOB h_debtags_maint debtags/maint/*.h debtags/maint/*.tcc )
file( GLOB h_axi axi/*.h )
file( GLOB h_utils utils/*.h )
-file( GLOB debtagstesth debtags/*.test.h debtags/maint/*.test.h )
-file( GLOB apttesth apt/*.test.h )
-file( GLOB axitesth axi/*.test.h )
-set( testh ${debtagstesth} ${apttesth} ${axitesth} )
+#file( GLOB debtagstesth debtags/*.test.h debtags/maint/*.test.h )
+#file( GLOB apttesth apt/*.test.h )
+#file( GLOB axitesth axi/*.test.h )
+#set( testh ${debtagstesth} ${apttesth} ${axitesth} )
include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
${TAGCOLL_INCLUDE_DIRS} ${WIBBLE_INCLUDE_DIRS} )
@@ -26,7 +28,10 @@ add_library( ept-static STATIC ${src} )
set_target_properties( ept PROPERTIES SOVERSION ${LIBEPT_SOVERSION} CLEAN_DIRECT_OUTPUT 1)
set_target_properties( ept-static PROPERTIES SOVERSION ${LIBEPT_SOVERSION} OUTPUT_NAME "ept" CLEAN_DIRECT_OUTPUT 1)
-set( TEST_ENV_DIR ${ept_BINARY_DIR}/test-env/ )
+add_executable(test-ept EXCLUDE_FROM_ALL utils/tests-main.cc ${tests})
+target_link_libraries(test-ept ept)
+add_test(test-ept test-ept)
+add_dependencies(check test-ept)
configure_file( ${ept_SOURCE_DIR}/config.h.cmake-in
${ept_BINARY_DIR}/config.h )
@@ -41,32 +46,6 @@ configure_file( ${ept_SOURCE_DIR}/libept.pc.in
# regression testing
link_directories( ${CMAKE_CURRENT_BINARY_DIR}/../lib )
link_libraries( ept )
-wibble_add_test( ept-test ${testh} )
-
-set( datastamp ${CMAKE_CURRENT_BINARY_DIR}/data-stamp )
-set( datadir ${CMAKE_CURRENT_SOURCE_DIR}/test-data )
-set( listfile wherever_debian_._Packages )
-
-wibble_check_target( ept-test ${datastamp} )
-
-execute_process( COMMAND dpkg --print-architecture OUTPUT_VARIABLE ARCH )
-string( REPLACE "\n" "" ARCH "${ARCH}" )
-
-add_custom_command(
- OUTPUT ${datastamp}
- COMMAND mkdir -p test-env/etc test-env/state/lists/partial
- test-env/cache test-env/debtags
- test-env/cache/archives/partial test-env/desktop
- COMMAND sed -e s,i386,${ARCH}, < ${datadir}/packagelist > test-env/state/lists/${listfile}
- COMMAND cp -a ${datadir}/etc/sources.list test-env/etc/
- COMMAND sed -e s,i386,${ARCH}, < ${datadir}/dpkg-status > test-env/dpkg-status
- COMMAND cp -a ${datadir}/desktop/*.desktop test-env/desktop/
- COMMAND cp ${datadir}/debtags/package-tags test-env/debtags/package-tags
- COMMAND cp ${datadir}/debtags/vocabulary test-env/debtags/vocabulary
- COMMAND mkdir -p test-env/debtags/empty
- COMMAND mkdir -p test-env/debtags/user
- COMMAND mkdir -p test-env/xapian/
- COMMAND touch data-stamp )
install( TARGETS ept ept-static
LIBRARY DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}
diff --git a/ept/apt/apt-test.cc b/ept/apt/apt-test.cc
new file mode 100644
index 0000000..7646010
--- /dev/null
+++ b/ept/apt/apt-test.cc
@@ -0,0 +1,209 @@
+#include "ept/test.h"
+#include "apt.h"
+#include <set>
+#include <algorithm>
+
+using namespace std;
+using namespace ept;
+using namespace ept::tests;
+using namespace ept::apt;
+
+namespace {
+
+struct AptTestEnvironment {
+ //ept::core::AptDatabase db;
+ AptTestEnvironment() {
+ pkgInitConfig (*_config);
+ _config->Set("Initialized", 1);
+ _config->Set("Dir", ".");
+ _config->Set("Dir::Cache", "cache");
+ _config->Set("Dir::State", "state");
+ _config->Set("Dir::Etc", "etc");
+ _config->Set("Dir::Etc::sourcelist", "sources.list");
+ _config->Set("Dir::State::status", "./dpkg-status");
+ pkgInitSystem (*_config, _system);
+ }
+};
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("iterators", []() {
+ // Check that iterations iterates among some packages
+ AptTestEnvironment env;
+ Apt apt;
+ Apt::iterator i = apt.begin();
+ wassert_true(i != apt.end());
+
+ size_t count = 0;
+ for (; i != apt.end(); ++i)
+ ++count;
+
+ wassert_true(count > 100);
+ });
+
+ add_method("apt_exists", []() {
+ // Check that iteration gives some well-known packages
+ AptTestEnvironment env;
+ Apt apt;
+ set<string> packages;
+
+ std::copy(apt.begin(), apt.end(), inserter(packages, packages.begin()));
+
+ wassert_true(packages.find("libsp1") != packages.end());
+ // TODO this exposes a bug somewhere... sp definitely is among
+ // the packages
+ // wassert_true(packages.find("sp") != packages.end());
+ wassert_true(packages.find("") == packages.end());
+ });
+
+ add_method("timestamp", []() {
+ // Check that timestamp gives some meaningful timestamp
+ AptTestEnvironment env;
+ Apt apt;
+ time_t ts = apt.timestamp();
+ wassert_true(ts > 1000000);
+ });
+
+ add_method("validity", []() {
+ // Check the package validator
+ AptTestEnvironment env;
+ Apt apt;
+ wassert_true(apt.isValid("apt"));
+ wassert_true(!apt.isValid("this-package-does-not-really-exists"));
+ });
+
+ add_method("versions", []() {
+ // Check the version instantiators
+ AptTestEnvironment env;
+ Apt apt;
+ std::string pkg("apt");
+ Version ver = apt.candidateVersion(pkg);
+ wassert_true(ver.isValid());
+
+ ver = apt.installedVersion(pkg);
+ wassert_true(ver.isValid());
+
+ ver = apt.anyVersion(pkg);
+ wassert_true(ver.isValid());
+
+ std::string pkg1("this-package-does-not-really-exists");
+ ver = apt.candidateVersion(pkg1);
+ wassert_true(!ver.isValid());
+
+ ver = apt.installedVersion(pkg1);
+ wassert_true(!ver.isValid());
+
+ ver = apt.anyVersion(pkg1);
+ wassert_true(!ver.isValid());
+ });
+
+ add_method("version_validity", []() {
+ // Check the version validator
+ AptTestEnvironment env;
+ Apt apt;
+ Version ver = apt.candidateVersion("apt");
+ wassert_true(apt.validate(ver) == ver);
+
+ ver = Version("this-package-does-not-really-exists", "0.1");
+ wassert_true(!apt.validate(ver).isValid());
+
+ ver = Version("apt", "0.31415");
+ wassert_true(!apt.validate(ver).isValid());
+ });
+
+ add_method("raw_record", []() {
+ // Check the raw record accessor
+ AptTestEnvironment env;
+ Apt apt;
+ string pkg("sp");
+ Version ver = apt.candidateVersion(pkg);
+ wassert_true(ver.isValid());
+ wassert_true(apt.validate(ver) == ver);
+
+ string record = apt.rawRecord(ver);
+ wassert_true(record.find("Package: sp") != string::npos);
+ wassert_true(record.find("Section: text") != string::npos);
+
+ record = apt.rawRecord(Version("sp", "0.31415"));
+ assert_eq(record, string());
+
+ assert_eq(apt.rawRecord(pkg), apt.rawRecord(apt.anyVersion(pkg)));
+ });
+
+ add_method("state", []() {
+ // Check the package state accessor
+ AptTestEnvironment env;
+ Apt apt;
+ PackageState s = apt.state("kdenetwork");
+ wassert_true(s.isValid());
+ wassert_true(s.isInstalled());
+
+ s = apt.state("this-package-does-not-really-exists");
+ wassert_true(!s.isValid());
+ });
+
+ add_method("record_iteration", []() {
+ // Check the record iterator (accessing with *)
+ AptTestEnvironment env;
+ Apt apt;
+ size_t count = 0;
+ for (Apt::record_iterator i = apt.recordBegin();
+ i != apt.recordEnd(); ++i)
+ {
+ wassert_true((*i).size() > 8);
+ assert_eq((*i).substr(0, 8), "Package:");
+ ++count;
+ }
+ wassert_true(count > 200);
+ });
+
+ add_method("record_iteration2", []() {
+ // Check the record iterator (accessing with ->)
+ AptTestEnvironment env;
+ Apt apt;
+ size_t count = 0;
+ for (Apt::record_iterator i = apt.recordBegin();
+ i != apt.recordEnd(); ++i)
+ {
+ wassert_true(i->size() > 8);
+ assert_eq(i->substr(0, 8), "Package:");
+ ++count;
+ }
+ wassert_true(count > 200);
+ });
+
+ add_method("stl_iteration", []() {
+ // Check that the iterators can be used with the algorithms
+ AptTestEnvironment env;
+ Apt apt;
+ vector<string> out;
+ std::copy(apt.begin(), apt.end(), back_inserter(out));
+ });
+
+ add_method("stl_record_iteration", []() {
+ // Check that the iterators can be used with the algorithms
+ AptTestEnvironment env;
+ Apt apt;
+ vector<string> out;
+ std::copy(apt.recordBegin(), apt.recordEnd(), back_inserter(out));
+ });
+
+ add_method("check_updates", []() {
+ // Check that checkUpdates will keep a working Apt object
+ AptTestEnvironment env;
+ Apt apt;
+ wassert_true(apt.isValid("apt"));
+ apt.checkCacheUpdates();
+ wassert_true(apt.isValid("apt"));
+ apt.invalidateTimestamp();
+ apt.checkCacheUpdates();
+ wassert_true(apt.isValid("apt"));
+ });
+ }
+} tests("apt_apt");
+
+}
diff --git a/ept/apt/apt.test.h b/ept/apt/apt.test.h
deleted file mode 100644
index ff4f315..0000000
--- a/ept/apt/apt.test.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <ept/test.h>
-#include <ept/apt/apt.h>
-#include <set>
-#include <algorithm>
-
-using namespace std;
-using namespace ept;
-using namespace ept::apt;
-
-struct TestApt : AptTestEnvironment {
- Apt apt;
-
- // Check that iterations iterates among some packages
- Test iterators()
- {
- Apt::iterator i = apt.begin();
- assert(i != apt.end());
-
- size_t count = 0;
- for (; i != apt.end(); ++i)
- ++count;
-
- assert(count > 100);
- }
-
- // Check that iteration gives some well-known packages
- Test aptExists()
- {
- set<string> packages;
-
- std::copy(apt.begin(), apt.end(), inserter(packages, packages.begin()));
-
- assert(packages.find("libsp1") != packages.end());
- // TODO this exposes a bug somewhere... sp definitely is among
- // the packages
- // assert(packages.find("sp") != packages.end());
- assert(packages.find("") == packages.end());
- }
-
- // Check that timestamp gives some meaningful timestamp
- Test timestamp()
- {
- time_t ts = apt.timestamp();
- assert(ts > 1000000);
- }
-
- // Check the package validator
- Test validity()
- {
- assert(apt.isValid("apt"));
- assert(!apt.isValid("this-package-does-not-really-exists"));
- }
-
- // Check the version instantiators
- Test versions()
- {
- std::string pkg("apt");
- Version ver = apt.candidateVersion(pkg);
- assert(ver.isValid());
-
- ver = apt.installedVersion(pkg);
- assert(ver.isValid());
-
- ver = apt.anyVersion(pkg);
- assert(ver.isValid());
-
- std::string pkg1("this-package-does-not-really-exists");
- ver = apt.candidateVersion(pkg1);
- assert(!ver.isValid());
-
- ver = apt.installedVersion(pkg1);
- assert(!ver.isValid());
-
- ver = apt.anyVersion(pkg1);
- assert(!ver.isValid());
- }
-
- // Check the version validator
- Test versionValidity()
- {
- Version ver = apt.candidateVersion("apt");
- assert(apt.validate(ver) == ver);
-
- ver = Version("this-package-does-not-really-exists", "0.1");
- assert(!apt.validate(ver).isValid());
-
- ver = Version("apt", "0.31415");
- assert(!apt.validate(ver).isValid());
- }
-
- // Check the raw record accessor
- Test rawRecord()
- {
- string pkg("sp");
- Version ver = apt.candidateVersion(pkg);
- assert(ver.isValid());
- assert(apt.validate(ver) == ver);
-
- string record = apt.rawRecord(ver);
- assert(record.find("Package: sp") != string::npos);
- assert(record.find("Section: text") != string::npos);
-
- record = apt.rawRecord(Version("sp", "0.31415"));
- assert_eq(record, string());
-
- assert_eq(apt.rawRecord(pkg), apt.rawRecord(apt.anyVersion(pkg)));
- }
-
- // Check the package state accessor
- Test state()
- {
- PackageState s = apt.state("kdenetwork");
- assert(s.isValid());
- assert(s.isInstalled());
-
- s = apt.state("this-package-does-not-really-exists");
- assert(!s.isValid());
- }
-
- // Check the record iterator (accessing with *)
- Test recordIteration()
- {
- size_t count = 0;
- for (Apt::record_iterator i = apt.recordBegin();
- i != apt.recordEnd(); ++i)
- {
- assert((*i).size() > 8);
- assert_eq((*i).substr(0, 8), "Package:");
- ++count;
- }
- assert(count > 200);
- }
-
- // Check the record iterator (accessing with ->)
- Test recordIteration2()
- {
- size_t count = 0;
- for (Apt::record_iterator i = apt.recordBegin();
- i != apt.recordEnd(); ++i)
- {
- assert(i->size() > 8);
- assert_eq(i->substr(0, 8), "Package:");
- ++count;
- }
- assert(count > 200);
- }
-
- // Check that the iterators can be used with the algorithms
- Test stlIteration()
- {
- vector<string> out;
- std::copy(apt.begin(), apt.end(), back_inserter(out));
- }
-
- // Check that the iterators can be used with the algorithms
- Test stlRecordIteration()
- {
- vector<string> out;
- std::copy(apt.recordBegin(), apt.recordEnd(), back_inserter(out));
- }
-
- // Check that checkUpdates will keep a working Apt object
- Test checkUpdates()
- {
- assert(apt.isValid("apt"));
- apt.checkCacheUpdates();
- assert(apt.isValid("apt"));
- apt.invalidateTimestamp();
- apt.checkCacheUpdates();
- assert(apt.isValid("apt"));
- }
-
-};
-
-// vim:set ts=4 sw=4:
diff --git a/ept/apt/packagerecord-test.cc b/ept/apt/packagerecord-test.cc
new file mode 100644
index 0000000..b421f5b
--- /dev/null
+++ b/ept/apt/packagerecord-test.cc
@@ -0,0 +1,126 @@
+#include "ept/test.h"
+#include "packagerecord.h"
+
+namespace std {
+ ostream& operator<<(ostream& out, const set<string>& s)
+ {
+ for (set<string>::const_iterator i = s.begin();
+ i != s.end(); ++i)
+ if (i == s.begin())
+ out << *i;
+ else
+ out << ", " << *i;
+ return out;
+ }
+}
+
+using namespace std;
+using namespace ept;
+using namespace ept::tests;
+using namespace ept::apt;
+
+namespace {
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("supported_fields", []() {
+ // Check that the supported fields are understood
+ string record =
+ "Package: apt\n"
+ "Priority: important\n"
+ "Section: admin\n"
+ "Installed-Size: 4368\n"
+ "Maintainer: APT Development Team <deity@lists.debian.org>\n"
+ "Architecture: amd64\n"
+ "Source: apt\n"
+ "Version: 0.6.46.4-0.1\n"
+ "Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)\n"
+ "Provides: libapt-pkg-libc6.3-6-3.11\n"
+ "Depends: libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring\n"
+ "Pre-Depends: debtags (maybe)\n"
+ "Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2\n"
+ "Recommends: debtags (maybe)\n"
+ "Enhances: debian\n"
+ "Conflicts: marameo\n"
+ "Filename: pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb\n"
+ "Size: 1436478\n"
+ "MD5sum: 1776421f80d6300c77a608e77a9f4a15\n"
+ "SHA1: 1bd7337d2df56d267632cf72ac930c0a4895898f\n"
+ "SHA256: b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda\n"
+ "Description: Advanced front-end for dpkg\n"
+ " This is Debian's next generation front-end for the dpkg package manager.\n"
+ " It provides the apt-get utility and APT dselect method that provides a\n"
+ " simpler, safer way to install and upgrade packages.\n"
+ " .\n"
+ " APT features complete installation ordering, multiple source capability\n"
+ " and several other unique features, see the Users Guide in apt-doc.\n"
+ "Build-Essential: yes\n"
+ "Tag: admin::package-management, filetransfer::ftp, filetransfer::http, hardware::storage:cd, interface::commandline, network::client, protocol::{ftp,http,ipv6}, role::program, suite::debian, use::downloading, use::searching, works-with::software:package\n";
+
+ PackageRecord p(record);
+
+ wassert(actual(p.size()) == 24u);
+
+ wassert(actual(p.package()) == "apt");
+ wassert(actual(p.priority()) == "important");
+ wassert(actual(p.section()) == "admin");
+ wassert(actual(p.installedSize()) == 4368u);
+ wassert(actual(p.maintainer()) == "APT Development Team <deity@lists.debian.org>");
+ wassert(actual(p.architecture()) == "amd64");
+ wassert(actual(p.source()) == "apt");
+ wassert(actual(p.version()) == "0.6.46.4-0.1");
+ wassert(actual(p.replaces()) == "libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)");
+ wassert(actual(p.provides()) == "libapt-pkg-libc6.3-6-3.11");
+ wassert(actual(p.depends()) == "libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring");
+ wassert(actual(p.preDepends()) == "debtags (maybe)");
+ wassert(actual(p.recommends()) == "debtags (maybe)");
+ wassert(actual(p.suggests()) == "aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2");
+ wassert(actual(p.enhances()) == "debian");
+ wassert(actual(p.conflicts()) == "marameo");
+ wassert(actual(p.filename()) == "pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb");
+ wassert(actual(p.packageSize()) == 1436478u);
+ wassert(actual(p.md5sum()) == "1776421f80d6300c77a608e77a9f4a15");
+ wassert(actual(p.sha1()) == "1bd7337d2df56d267632cf72ac930c0a4895898f");
+ wassert(actual(p.sha256()) == "b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda");
+ wassert(actual(p.description()) == "Advanced front-end for dpkg\n"
+ " This is Debian's next generation front-end for the dpkg package manager.\n"
+ " It provides the apt-get utility and APT dselect method that provides a\n"
+ " simpler, safer way to install and upgrade packages.\n"
+ " .\n"
+ " APT features complete installation ordering, multiple source capability\n"
+ " and several other unique features, see the Users Guide in apt-doc.");
+ wassert(actual(p.shortDescription()) == "Advanced front-end for dpkg");
+ wassert(actual(p.longDescription()) ==
+ "This is Debian's next generation front-end for the dpkg package manager.\n"
+ " It provides the apt-get utility and APT dselect method that provides a\n"
+ " simpler, safer way to install and upgrade packages.\n"
+ " .\n"
+ " APT features complete installation ordering, multiple source capability\n"
+ " and several other unique features, see the Users Guide in apt-doc.");
+ wassert(actual(p.buildEssential()) == true);
+
+ std::set<std::string> tags;
+ tags.insert("admin::package-management");
+ tags.insert("filetransfer::ftp");
+ tags.insert("filetransfer::http");
+ tags.insert("hardware::storage:cd");
+ tags.insert("interface::commandline");
+ tags.insert("network::client");
+ tags.insert("protocol::ftp");
+ tags.insert("protocol::http");
+ tags.insert("protocol::ipv6");
+ tags.insert("role::program");
+ tags.insert("suite::debian");
+ tags.insert("use::downloading");
+ tags.insert("use::searching");
+ tags.insert("works-with::software:package");
+ wassert(actual(p.tag()) == tags);
+ });
+ }
+} tests("apt_packagerecord");
+
+}
diff --git a/ept/apt/packagerecord.test.h b/ept/apt/packagerecord.test.h
deleted file mode 100644
index 657cbab..0000000
--- a/ept/apt/packagerecord.test.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <ept/test.h>
-#include <ept/apt/packagerecord.h>
-
-namespace std {
- ostream& operator<<(ostream& out, const set<string>& s)
- {
- for (set<string>::const_iterator i = s.begin();
- i != s.end(); ++i)
- if (i == s.begin())
- out << *i;
- else
- out << ", " << *i;
- return out;
- }
-}
-
-using namespace std;
-using namespace ept;
-using namespace ept::apt;
-
-struct TestAptPackagerecord {
-
- // Check that the supported fields are understood
- Test supportedFields()
- {
- string record =
- "Package: apt\n"
- "Priority: important\n"
- "Section: admin\n"
- "Installed-Size: 4368\n"
- "Maintainer: APT Development Team <deity@lists.debian.org>\n"
- "Architecture: amd64\n"
- "Source: apt\n"
- "Version: 0.6.46.4-0.1\n"
- "Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)\n"
- "Provides: libapt-pkg-libc6.3-6-3.11\n"
- "Depends: libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring\n"
- "Pre-Depends: debtags (maybe)\n"
- "Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2\n"
- "Recommends: debtags (maybe)\n"
- "Enhances: debian\n"
- "Conflicts: marameo\n"
- "Filename: pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb\n"
- "Size: 1436478\n"
- "MD5sum: 1776421f80d6300c77a608e77a9f4a15\n"
- "SHA1: 1bd7337d2df56d267632cf72ac930c0a4895898f\n"
- "SHA256: b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda\n"
- "Description: Advanced front-end for dpkg\n"
- " This is Debian's next generation front-end for the dpkg package manager.\n"
- " It provides the apt-get utility and APT dselect method that provides a\n"
- " simpler, safer way to install and upgrade packages.\n"
- " .\n"
- " APT features complete installation ordering, multiple source capability\n"
- " and several other unique features, see the Users Guide in apt-doc.\n"
- "Build-Essential: yes\n"
- "Tag: admin::package-management, filetransfer::ftp, filetransfer::http, hardware::storage:cd, interface::commandline, network::client, protocol::{ftp,http,ipv6}, role::program, suite::debian, use::downloading, use::searching, works-with::software:package\n";
-
- PackageRecord p(record);
-
- assert_eq(p.size(), 24u);
-
- assert_eq(p.package(), "apt");
- assert_eq(p.priority(), "important");
- assert_eq(p.section(), "admin");
- assert_eq(p.installedSize(), 4368u);
- assert_eq(p.maintainer(), "APT Development Team <deity@lists.debian.org>");
- assert_eq(p.architecture(), "amd64");
- assert_eq(p.source(), "apt");
- assert_eq(p.version(), "0.6.46.4-0.1");
- assert_eq(p.replaces(), "libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)");
- assert_eq(p.provides(), "libapt-pkg-libc6.3-6-3.11");
- assert_eq(p.depends(), "libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring");
- assert_eq(p.preDepends(), "debtags (maybe)");
- assert_eq(p.recommends(), "debtags (maybe)");
- assert_eq(p.suggests(), "aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2");
- assert_eq(p.enhances(), "debian");
- assert_eq(p.conflicts(), "marameo");
- assert_eq(p.filename(), "pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb");
- assert_eq(p.packageSize(), 1436478u);
- assert_eq(p.md5sum(), "1776421f80d6300c77a608e77a9f4a15");
- assert_eq(p.sha1(), "1bd7337d2df56d267632cf72ac930c0a4895898f");
- assert_eq(p.sha256(), "b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda");
- assert_eq(p.description(), "Advanced front-end for dpkg\n"
- " This is Debian's next generation front-end for the dpkg package manager.\n"
- " It provides the apt-get utility and APT dselect method that provides a\n"
- " simpler, safer way to install and upgrade packages.\n"
- " .\n"
- " APT features complete installation ordering, multiple source capability\n"
- " and several other unique features, see the Users Guide in apt-doc.");
- assert_eq(p.shortDescription(), "Advanced front-end for dpkg");
- assert_eq(p.longDescription(),
- "This is Debian's next generation front-end for the dpkg package manager.\n"
- " It provides the apt-get utility and APT dselect method that provides a\n"
- " simpler, safer way to install and upgrade packages.\n"
- " .\n"
- " APT features complete installation ordering, multiple source capability\n"
- " and several other unique features, see the Users Guide in apt-doc.");
- assert_eq(p.buildEssential(), true);
-
- std::set<std::string> tags;
- tags.insert("admin::package-management");
- tags.insert("filetransfer::ftp");
- tags.insert("filetransfer::http");
- tags.insert("hardware::storage:cd");
- tags.insert("interface::commandline");
- tags.insert("network::client");
- tags.insert("protocol::ftp");
- tags.insert("protocol::http");
- tags.insert("protocol::ipv6");
- tags.insert("role::program");
- tags.insert("suite::debian");
- tags.insert("use::downloading");
- tags.insert("use::searching");
- tags.insert("works-with::software:package");
- assert_eq(p.tag(), tags);
- }
-
-};
-
-// vim:set ts=4 sw=4:
diff --git a/ept/apt/recordparser-test.cc b/ept/apt/recordparser-test.cc
new file mode 100644
index 0000000..4e01e6b
--- /dev/null
+++ b/ept/apt/recordparser-test.cc
@@ -0,0 +1,200 @@
+#include "ept/test.h"
+#include "recordparser.h"
+
+using namespace ept::tests;
+using namespace std;
+using namespace ept;
+using namespace ept::apt;
+
+namespace {
+
+const char* test_record =
+ "A:\n"
+ "D: da de di do du\n"
+ "B: b\n"
+ "C: c \n"
+ "Desc: this is the beginning\n"
+ " this is the continuation\n"
+ " this is the end\n";
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("parsing", []() {
+ // Check that the fields are identified and broken up correctly
+ RecordParser p(test_record);
+
+ wassert(actual(p.record()) == test_record);
+ wassert(actual(p.size()) == 5u);
+ });
+
+ add_method("field_tuples", []() {
+ RecordParser p(test_record);
+ wassert(actual(p.field(0)) == "A:\n");
+ wassert(actual(p.field(1)) == "D: da de di do du\n");
+ wassert(actual(p.field(2)) == "B: b\n");
+ wassert(actual(p.field(3)) == "C: c \n");
+ wassert(actual(p.field(4)) == "Desc: this is the beginning\n this is the continuation\n this is the end\n");
+ });
+
+ add_method("field_keys", []() {
+ RecordParser p(test_record);
+ wassert(actual(p.name(0)) == "A");
+ wassert(actual(p.name(1)) == "D");
+ wassert(actual(p.name(2)) == "B");
+ wassert(actual(p.name(3)) == "C");
+ wassert(actual(p.name(4)) == "Desc");
+ });
+
+ add_method("field_values", []() {
+ RecordParser p(test_record);
+ wassert(actual(p[0]) == "");
+ wassert(actual(p[1]) == "da de di do du");
+ wassert(actual(p[2]) == "b");
+ wassert(actual(p[3]) == "c");
+ wassert(actual(p[4]) == "this is the beginning\n this is the continuation\n this is the end");
+ });
+
+ add_method("find_byname", []() {
+ // Check that the field search by name finds all the fields
+ RecordParser p(test_record);
+
+ wassert(actual(p.index("A")) == 0u);
+ wassert(actual(p.index("D")) == 1u);
+ wassert(actual(p.index("B")) == 2u);
+ wassert(actual(p.index("C")) == 3u);
+ wassert(actual(p.index("Desc")) == 4u);
+
+ wassert(actual(p.name(p.index("A"))) == "A");
+ wassert(actual(p.name(p.index("B"))) == "B");
+ wassert(actual(p.name(p.index("C"))) == "C");
+ wassert(actual(p.name(p.index("D"))) == "D");
+ wassert(actual(p.name(p.index("Desc"))) == "Desc");
+ });
+
+ add_method("indexing", []() {
+ RecordParser p(test_record);
+ wassert(actual(p["A"]) == "");
+ wassert(actual(p["B"]) == "b");
+ wassert(actual(p["C"]) == "c");
+ wassert(actual(p["D"]) == "da de di do du");
+ wassert(actual(p["Desc"]) == "this is the beginning\n this is the continuation\n this is the end");
+ });
+
+ add_method("missing_behaviour", []() {
+ RecordParser p(test_record);
+ // Missing fields give empty strings
+ wassert(actual(p.field(100)) == "");
+ wassert(actual(p.name(100)) == "");
+ wassert(actual(p[100]) == "");
+ wassert(actual(p["Missing"]) == "");
+ });
+
+ add_method("rescan", []() {
+ // Check that scanning twice replaces the old fields
+ std::string record =
+ "A: a\n"
+ "B: b\n"
+ "C: c\n";
+
+ RecordParser p(record);
+ wassert(actual(p.size()) == 3u);
+ wassert(actual(p["A"]) == "a");
+ wassert(actual(p["B"]) == "b");
+ wassert(actual(p["C"]) == "c");
+
+ std::string record1 =
+ "Foo: bar\n"
+ "A: different\n";
+
+ p.scan(record1);
+
+ //for (size_t i = 0; i < p.size(); ++i)
+ // cerr << ">> " << i << "==" << p.index(p.name(i)) << " " << p.name(i) << " " << p[i] << endl;
+
+ wassert(actual(p.size()) == 2u);
+ wassert(actual(p["A"]) == "different");
+ wassert(actual(p["B"]) == "");
+ wassert(actual(p["C"]) == "");
+ wassert(actual(p["Foo"]) == "bar");
+ });
+
+ add_method("real_life", []() {
+ // Real-life example
+ string record =
+ "Package: apt\n"
+ "Priority: important\n"
+ "Section: admin\n"
+ "Installed-Size: 4368\n"
+ "Maintainer: APT Development Team <deity@lists.debian.org>\n"
+ "Architecture: amd64\n"
+ "Version: 0.6.46.4-0.1\n"
+ "Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)\n"
+ "Provides: libapt-pkg-libc6.3-6-3.11\n"
+ "Depends: libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring\n"
+ "Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2\n"
+ "Filename: pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb\n"
+ "Size: 1436478\n"
+ "MD5sum: 1776421f80d6300c77a608e77a9f4a15\n"
+ "SHA1: 1bd7337d2df56d267632cf72ac930c0a4895898f\n"
+ "SHA256: b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda\n"
+ "Description: Advanced front-end for dpkg\n"
+ " This is Debian's next generation front-end for the dpkg package manager.\n"
+ " It provides the apt-get utility and APT dselect method that provides a\n"
+ " simpler, safer way to install and upgrade packages.\n"
+ " .\n"
+ " APT features complete installation ordering, multiple source capability\n"
+ " and several other unique features, see the Users Guide in apt-doc.\n"
+ "Build-Essential: yes\n"
+ "Tag: admin::package-management, filetransfer::ftp, filetransfer::http, hardware::storage:cd, interface::commandline, network::client, protocol::{ftp,http,ipv6}, role::program, suite::debian, use::downloading, use::searching, works-with::software:package\n";
+ RecordParser p(record);
+
+ wassert(actual(p.size()) == 19u);
+
+ string rec1;
+ for (size_t i = 0; i < p.size(); ++i)
+ rec1 += p.field(i);
+ wassert(actual(record) == rec1);
+ });
+
+ add_method("buffer_termination", []() {
+ // Various buffer termination patterns
+ std::string record =
+ "A: a\n"
+ "B: b";
+
+ RecordParser p(record);
+ wassert(actual(p.size()) == 2u);
+ wassert(actual(p["A"]) == "a");
+ wassert(actual(p["B"]) == "b");
+ });
+
+ add_method("buffer_termination2", []() {
+ std::string record =
+ "A: a\n"
+ "B: b\n\n";
+
+ RecordParser p(record);
+ wassert(actual(p.size()) == 2u);
+ wassert(actual(p["A"]) == "a");
+ wassert(actual(p["B"]) == "b");
+ });
+
+ add_method("buffer_termination3", []() {
+ std::string record =
+ "A: a\n"
+ "B: b\n\n"
+ "C: c\n";
+
+ RecordParser p(record);
+ wassert(actual(p.size()) == 2u);
+ wassert(actual(p["A"]) == "a");
+ wassert(actual(p["B"]) == "b");
+ });
+ }
+} tests("apt_recordparser");
+
+}
diff --git a/ept/apt/recordparser.test.h b/ept/apt/recordparser.test.h
deleted file mode 100644
index 629008f..0000000
--- a/ept/apt/recordparser.test.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <ept/test.h>
-#include <ept/apt/recordparser.h>
-
-//#include <iostream>
-
-using namespace std;
-using namespace ept;
-using namespace ept::apt;
-
-struct TestAptRecordparser {
- std::string record;
- TestAptRecordparser()
- {
- record =
- "A:\n"
- "D: da de di do du\n"
- "B: b\n"
- "C: c \n"
- "Desc: this is the beginning\n"
- " this is the continuation\n"
- " this is the end\n";
- }
-
- // Check that the fields are identified and broken up correctly
- Test parsing()
- {
- RecordParser p(record);
-
- assert_eq(p.record(), record);
- assert_eq(p.size(), 5u);
- }
-
- Test fieldTuples()
- {
- RecordParser p(record);
- assert_eq(p.field(0), "A:\n");
- assert_eq(p.field(1), "D: da de di do du\n");
- assert_eq(p.field(2), "B: b\n");
- assert_eq(p.field(3), "C: c \n");
- assert_eq(p.field(4), "Desc: this is the beginning\n this is the continuation\n this is the end\n");
- }
-
- Test fieldKeys()
- {
- RecordParser p(record);
- assert_eq(p.name(0), "A");
- assert_eq(p.name(1), "D");
- assert_eq(p.name(2), "B");
- assert_eq(p.name(3), "C");
- assert_eq(p.name(4), "Desc");
- }
-
- Test fieldValues()
- {
- RecordParser p(record);
- assert_eq(p[0], "");
- assert_eq(p[1], "da de di do du");
- assert_eq(p[2], "b");
- assert_eq(p[3], "c");
- assert_eq(p[4], "this is the beginning\n this is the continuation\n this is the end");
- }
-
- // Check that the field search by name finds all the fields
- Test findByName()
- {
- RecordParser p(record);
-
- assert_eq(p.index("A"), 0u);
- assert_eq(p.index("D"), 1u);
- assert_eq(p.index("B"), 2u);
- assert_eq(p.index("C"), 3u);
- assert_eq(p.index("Desc"), 4u);
-
- assert_eq(p.name(p.index("A")), "A");
- assert_eq(p.name(p.index("B")), "B");
- assert_eq(p.name(p.index("C")), "C");
- assert_eq(p.name(p.index("D")), "D");
- assert_eq(p.name(p.index("Desc")), "Desc");
- }
-
- Test indexing()
- {
- RecordParser p(record);
- assert_eq(p["A"], "");
- assert_eq(p["B"], "b");
- assert_eq(p["C"], "c");
- assert_eq(p["D"], "da de di do du");
- assert_eq(p["Desc"], "this is the beginning\n this is the continuation\n this is the end");
- }
-
- Test missingBehaviour()
- {
- RecordParser p(record);
- // Missing fields give empty strings
- assert_eq(p.field(100), "");
- assert_eq(p.name(100), "");
- assert_eq(p[100], "");
- assert_eq(p["Missing"], "");
- }
-
- // Check that scanning twice replaces the old fields
- Test rescan()
- {
- std::string record =
- "A: a\n"
- "B: b\n"
- "C: c\n";
-
- RecordParser p(record);
- assert_eq(p.size(), 3u);
- assert_eq(p["A"], "a");
- assert_eq(p["B"], "b");
- assert_eq(p["C"], "c");
-
- std::string record1 =
- "Foo: bar\n"
- "A: different\n";
-
- p.scan(record1);
-
- //for (size_t i = 0; i < p.size(); ++i)
- // cerr << ">> " << i << "==" << p.index(p.name(i)) << " " << p.name(i) << " " << p[i] << endl;
-
- assert_eq(p.size(), 2u);
- assert_eq(p["A"], "different");
- assert_eq(p["B"], "");
- assert_eq(p["C"], "");
- assert_eq(p["Foo"], "bar");
- }
-
- // Real-life example
- Test realLife()
- {
- string record =
- "Package: apt\n"
- "Priority: important\n"
- "Section: admin\n"
- "Installed-Size: 4368\n"
- "Maintainer: APT Development Team <deity@lists.debian.org>\n"
- "Architecture: amd64\n"
- "Version: 0.6.46.4-0.1\n"
- "Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)\n"
- "Provides: libapt-pkg-libc6.3-6-3.11\n"
- "Depends: libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring\n"
- "Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2\n"
- "Filename: pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb\n"
- "Size: 1436478\n"
- "MD5sum: 1776421f80d6300c77a608e77a9f4a15\n"
- "SHA1: 1bd7337d2df56d267632cf72ac930c0a4895898f\n"
- "SHA256: b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda\n"
- "Description: Advanced front-end for dpkg\n"
- " This is Debian's next generation front-end for the dpkg package manager.\n"
- " It provides the apt-get utility and APT dselect method that provides a\n"
- " simpler, safer way to install and upgrade packages.\n"
- " .\n"
- " APT features complete installation ordering, multiple source capability\n"
- " and several other unique features, see the Users Guide in apt-doc.\n"
- "Build-Essential: yes\n"
- "Tag: admin::package-management, filetransfer::ftp, filetransfer::http, hardware::storage:cd, interface::commandline, network::client, protocol::{ftp,http,ipv6}, role::program, suite::debian, use::downloading, use::searching, works-with::software:package\n";
- RecordParser p(record);
-
- assert_eq(p.size(), 19u);
-
- string rec1;
- for (size_t i = 0; i < p.size(); ++i)
- rec1 += p.field(i);
- assert_eq(record, rec1);
- }
-
- // Various buffer termination patterns
- Test bufferTermination()
- {
- std::string record =
- "A: a\n"
- "B: b";
-
- RecordParser p(record);
- assert_eq(p.size(), 2u);
- assert_eq(p["A"], "a");
- assert_eq(p["B"], "b");
- }
-
- Test bufferTermination2()
- {
- std::string record =
- "A: a\n"
- "B: b\n\n";
-
- RecordParser p(record);
- assert_eq(p.size(), 2u);
- assert_eq(p["A"], "a");
- assert_eq(p["B"], "b");
- }
-
- Test bufferTermination3()
- {
- std::string record =
- "A: a\n"
- "B: b\n\n"
- "C: c\n";
-
- RecordParser p(record);
- assert_eq(p.size(), 2u);
- assert_eq(p["A"], "a");
- assert_eq(p["B"], "b");
- }
-
-};
-
-// vim:set ts=4 sw=4:
diff --git a/ept/apt/version-test.cc b/ept/apt/version-test.cc
new file mode 100644
index 0000000..0fac7dc
--- /dev/null
+++ b/ept/apt/version-test.cc
@@ -0,0 +1,119 @@
+#include "ept/test.h"
+#include "version.h"
+
+using namespace std;
+using namespace ept::tests;
+using namespace ept::apt;
+
+namespace {
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("invalid", []() {
+ // Basic test for invalid version
+ Version test;
+
+ wassert(actual(test.name()) == "");
+ wassert(actual(test.version()) == "");
+ wassert(actual(test.isValid()) == false);
+
+ string p = test.name();
+
+ wassert(actual(p) == string());
+ });
+
+ add_method("basic", []() {
+ // Basic test for version
+ Version test("test", "1.0");
+
+ wassert(actual(test.name()) == "test");
+ wassert(actual(test.version()) == "1.0");
+ wassert(actual(test.isValid()) == true);
+
+ string p = test.name();
+
+ wassert(actual(p) == "test");
+
+ Version v(p, "1.1");
+ wassert(actual(v.name()) == "test");
+ wassert(actual(v.version()) == "1.1");
+ wassert(actual(v.isValid()) == true);
+ });
+
+ add_method("comparison", []() {
+ // Comparison semanthics
+ Version test("test", "1.0");
+ Version test1("test", "1.0");
+
+ wassert_true(test == test1);
+ wassert_true(! (test != test1));
+ wassert_true(! (test < test1));
+ wassert_true(! (test > test1));
+ wassert_true(test <= test1);
+ wassert_true(test >= test1);
+
+
+ Version test2("test2", "1.0");
+
+ wassert_true(test != test2);
+ wassert_true(test != test2);
+ wassert_true(test < test2);
+ wassert_true(! (test > test2));
+ wassert_true(test <= test2);
+ wassert_true(! (test >= test2));
+
+
+ Version test3("test", "2.0");
+
+ wassert_true(test != test3);
+ wassert_true(test != test3);
+ wassert_true(test < test3);
+ wassert_true(! (test > test3));
+ wassert_true(test <= test3);
+ wassert_true(! (test >= test3));
+ });
+
+ add_method("value_copy", []() {
+ // Value-copy semanthics
+ Version test("test", "1.0");
+ Version test1 = test;
+
+ wassert_true(test == test1);
+
+ Version test2;
+ test2 = test;
+ wassert_true(test == test2);
+ wassert_true(test1 == test2);
+
+ Version test3("test", "1.0");
+ wassert_true(test == test3);
+ wassert_true(test1 == test3);
+ wassert_true(test2 == test3);
+ });
+
+ add_method("upstream_version", []() {
+ // Extraction of upstream version
+ wassert(actual(Version("a", "10.0").upstreamVersion()) == "10.0");
+ wassert(actual(Version("a", "10.0-1").upstreamVersion()) == "10.0");
+ wassert(actual(Version("a", "10.0~foo.1-1.0").upstreamVersion()) == "10.0~foo.1");
+ wassert(actual(Version("a", "1.0:10.0~foo.1-1.0").upstreamVersion()) == "10.0~foo.1");
+ });
+
+ add_method("policy_comparison", []() {
+ // Debian policy comparison semanthics
+ wassert_true(Version("a", "10.0") > Version("a", "2.1"));
+ wassert_true(Version("a", "1:10.0") < Version("a", "2:2.1"));
+ wassert_true(Version("a", "10.0-1") < Version("a", "10.0-2"));
+ wassert_true(Version("a", "10.0-2") > Version("a", "10.0-1"));
+ wassert_true(Version("a", "1:10.0-1") <= Version("a", "1:10.0-1"));
+ wassert_true(Version("a", "1:10.0-1") >= Version("a", "1:10.0-1"));
+ // TODO: add more
+ });
+ }
+} tests("apt_version");
+
+}
diff --git a/ept/apt/version.test.h b/ept/apt/version.test.h
deleted file mode 100644
index a06a5c6..0000000
--- a/ept/apt/version.test.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <ept/test.h>
-#include <ept/apt/version.h>
-
-using namespace std;
-using namespace ept::apt;
-
-struct TestAptVersion {
-
- // Basic test for invalid version
- Test invalid()
- {
- Version test;
-
- assert_eq(test.name(), "");
- assert_eq(test.version(), "");
- assert_eq(test.isValid(), false);
-
- string p = test.name();
-
- assert_eq(p, string());
- }
-
- // Basic test for version
- Test basic()
- {
- Version test("test", "1.0");
-
- assert_eq(test.name(), "test");
- assert_eq(test.version(), "1.0");
- assert_eq(test.isValid(), true);
-
- string p = test.name();
-
- assert_eq(p, "test");
-
- Version v(p, "1.1");
- assert_eq(v.name(), "test");
- assert_eq(v.version(), "1.1");
- assert_eq(v.isValid(), true);
- }
-
- // Comparison semanthics
- Test comparison()
- {
- Version test("test", "1.0");
- Version test1("test", "1.0");
-
- assert(test == test1);
- assert(! (test != test1));
- assert(! (test < test1));
- assert(! (test > test1));
- assert(test <= test1);
- assert(test >= test1);
-
-
- Version test2("test2", "1.0");
-
- assert(test != test2);
- assert(test != test2);
- assert(test < test2);
- assert(! (test > test2));
- assert(test <= test2);
- assert(! (test >= test2));
-
-
- Version test3("test", "2.0");
-
- assert(test != test3);
- assert(test != test3);
- assert(test < test3);
- assert(! (test > test3));
- assert(test <= test3);
- assert(! (test >= test3));
- }
-
- // Value-copy semanthics
- Test valueCopy()
- {
- Version test("test", "1.0");
- Version test1 = test;
-
- assert(test == test1);
-
- Version test2;
- test2 = test;
- assert(test == test2);
- assert(test1 == test2);
-
- Version test3("test", "1.0");
- assert(test == test3);
- assert(test1 == test3);
- assert(test2 == test3);
- }
-
- // Extraction of upstream version
- Test upstreamVersion()
- {
- assert_eq(Version("a", "10.0").upstreamVersion(), "10.0");
- assert_eq(Version("a", "10.0-1").upstreamVersion(), "10.0");
- assert_eq(Version("a", "10.0~foo.1-1.0").upstreamVersion(), "10.0~foo.1");
- assert_eq(Version("a", "1.0:10.0~foo.1-1.0").upstreamVersion(), "10.0~foo.1");
- }
-
- // Debian policy comparison semanthics
- Test policyComparison()
- {
- assert(Version("a", "10.0") > Version("a", "2.1"));
- assert(Version("a", "1:10.0") < Version("a", "2:2.1"));
- assert(Version("a", "10.0-1") < Version("a", "10.0-2"));
- assert(Version("a", "10.0-2") > Version("a", "10.0-1"));
- assert(Version("a", "1:10.0-1") <= Version("a", "1:10.0-1"));
- assert(Version("a", "1:10.0-1") >= Version("a", "1:10.0-1"));
- // TODO: add more
- }
-
-};
-
-// vim:set ts=4 sw=4:
diff --git a/ept/axi/axi-test.cc b/ept/axi/axi-test.cc
new file mode 100644
index 0000000..e8d7920
--- /dev/null
+++ b/ept/axi/axi-test.cc
@@ -0,0 +1,37 @@
+#include "ept/test.h"
+#include "axi.h"
+#include "ept/apt/apt.h"
+#include <wibble/sys/fs.h>
+#include <set>
+
+using namespace ept::tests;
+using namespace std;
+using namespace ept;
+
+namespace {
+
+struct DirMaker
+{
+ DirMaker(const std::string& name)
+ {
+ wibble::sys::fs::mkdirIfMissing(name, 0755);
+ }
+};
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("empty", []() {
+ // Access an empty index
+ DirMaker md("xapian");
+ apt::Apt apt;
+ axi::OverrideIndexDir oid("./empty");
+ wassert(actual(axi::timestamp()) == 0);
+ });
+ }
+} tests("axi");
+
+}
diff --git a/ept/axi/axi.test.h b/ept/axi/axi.test.h
deleted file mode 100644
index 5481bd8..0000000
--- a/ept/axi/axi.test.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*-
-/*
- * popcon test
- *
- * Copyright (C) 2007 Enrico Zini <enrico@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <ept/test.h>
-#include <ept/axi/axi.h>
-#include <ept/apt/apt.h>
-#include <wibble/sys/fs.h>
-#include <set>
-
-using namespace std;
-using namespace ept;
-
-struct DirMaker
-{
- DirMaker(const std::string& name)
- {
- wibble::sys::fs::mkdirIfMissing(name, 0755);
- }
-};
-
-struct TestAxi : AptTestEnvironment
-{
- DirMaker md;
- axi::OverrideIndexDir oid;
- apt::Apt apt;
-
- TestAxi()
- : md( TEST_ENV_DIR "xapian"), oid( TEST_ENV_DIR "xapian")
- {
- }
-
-// Access an empty index
- Test empty()
- {
- axi::OverrideIndexDir oid("./empty");
- assert_eq(axi::timestamp(), 0);
- }
-};
-
-// vim:set ts=4 sw=4:
diff --git a/ept/debtags/debtags-test.cc b/ept/debtags/debtags-test.cc
new file mode 100644
index 0000000..3a8fca5
--- /dev/null
+++ b/ept/debtags/debtags-test.cc
@@ -0,0 +1,167 @@
+#include "debtags.h"
+#include <ept/test.h>
+#include <wibble/operators.h>
+#include <cstdio>
+
+using namespace tagcoll;
+using namespace std;
+using namespace ept;
+using namespace ept::debtags;
+using namespace ept::tests;
+using namespace wibble::operators;
+
+#define testfile TEST_ENV_DIR "debtags/package-tags"
+
+namespace {
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("iterate", []() {
+ EnvOverride eo("DEBTAGS_TAGS", testfile);
+ Debtags debtags;
+ for (Debtags::const_iterator i = debtags.begin(); i != debtags.end(); ++i)
+ {
+ *i;
+ i->first;
+ i->second;
+ }
+ });
+
+ add_method("lookup_tags", []() {
+ EnvOverride eo("DEBTAGS_TAGS", testfile);
+ Debtags debtags;
+ string p("debtags");
+ std::set<std::string> tags = debtags.getTagsOfItem(p);
+ wassert(actual(tags.empty()).isfalse());
+
+#if 0
+ for ( std::set< Tag >::iterator i = tags.begin(); i != tags.end(); ++ i ) {
+ std::cerr << i->id() << ": " << i->fullname() << std::endl;
+ }
+ std::cerr << "---" << std::endl;
+ Tag t = voc().tagByName( "interface::commandline" );
+ std::cerr << t.id() << ": " << t.fullname() << std::endl;
+#endif
+
+ wassert(actual(tags.size()) == 8u);
+ wassert(actual(tags.find("devel::buildtools") != tags.end()).istrue());
+ wassert(actual(tags.find("implemented-in::c++") != tags.end()).istrue());
+ wassert(actual(tags.find("interface::commandline") != tags.end()).istrue());
+ wassert(actual(tags.find("role::program") != tags.end()).istrue());
+ wassert(actual(tags.find("scope::application") != tags.end()).istrue());
+ wassert(actual(tags.find("suite::debian") != tags.end()).istrue());
+ wassert(actual(tags.find("use::searching") != tags.end()).istrue());
+ wassert(actual(tags.find("works-with::software:package") != tags.end()).istrue());
+ });
+
+ add_method("lookup_packages", []() {
+ using namespace std;
+ EnvOverride eo("DEBTAGS_TAGS", testfile);
+ Debtags debtags;
+
+ /* Get the 'debtags' package */
+ string p("debtags");
+
+ /* Get its tags */
+ std::set<std::string> tags = debtags.getTagsOfItem(p);
+ wassert(actual(tags.empty()).isfalse());
+
+ /*
+ cerr << "Intersection size: " << endl;
+ using namespace wibble::operators;
+ std::set<Tag>::const_iterator dbgi = tags.begin();
+ cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl;
+ std::set<int> dbgres = debtags.tagdb().getItemsHavingTag(dbgi->id());
+ std::set<Package> dbgpres = debtags.getItemsHavingTag(*dbgi);
+ cerr << " #pkgs " << dbgres.size() << " == " << dbgpres.size() << endl;
+ cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl;
+ cerr << " "; ppset(dbgpres); cerr << endl;
+ cerr << " "; piset(dbgres); cerr << endl;
+ for (++dbgi ; dbgi != tags.end(); ++dbgi)
+ {
+ cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl;
+ std::set<Package> dbgpkgs = debtags.getItemsHavingTag(*dbgi);
+ std::set<int> dbgids = debtags.tagdb().getItemsHavingTag(dbgi->id());
+ cerr << " "; ppset(dbgpkgs); cerr << endl;
+ cerr << " "; piset(dbgids); cerr << endl;
+ cerr << " #pkgs " << dbgpkgs.size() << " == " << dbgids.size() << endl;
+ dbgres &= dbgids;
+ dbgpres &= dbgpkgs;
+ cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl;
+ }
+ cerr << " " << dbgres.size() << endl << "Results: " << endl;
+ for (std::set<int>::const_iterator i = dbgres.begin(); i != dbgres.end(); ++i)
+ cerr << " " << *i << endl;
+ */
+
+
+ // cerr << "Tags of debtags: ";
+ // for (std::set<Tag>::const_iterator i = tags.begin(); i != tags.end(); ++i)
+ // {
+ // cerr << " " + i->fullname() << endl;
+ // std::set<Package> packages = debtags.getItemsHavingTag(*i);
+ // for (std::set<Package>::const_iterator p = packages.begin();
+ // p != packages.end(); ++p)
+ // cerr << " PKG " << p->name() << endl;
+ // }
+ // cerr << endl;
+
+ /* Get the items for the tagset of 'debtags' */
+ std::set<string> packages = debtags.getItemsHavingTags(tags);
+ //cerr << packages.size() << endl;
+ wassert(actual(packages.empty()).isfalse());
+ /*
+ for ( std::set< Package >::iterator i = packages.begin(); i != packages.end(); ++ i )
+ std::cerr << i->name() << std::endl;
+ std::cerr << "---" << std::endl;
+ std::cerr << p.name() << std::endl;
+ */
+ /* They should at least contain 'debtags' */
+ wassert(actual(p <= packages).istrue());
+
+ /* Get one of the tags of 'debtags' */
+ std::string tag = *tags.begin();
+
+ /* Get its items */
+ {
+ /* Need this workaround until I figure out how to tell the new GCC
+ * that TagDB is a TDBReadonlyDiskIndex and should behave as such
+ */
+ std::set<std::string> ts;
+ ts.insert(tag);
+ packages = debtags.getItemsHavingTags(ts);
+ }
+ //packages = c.debtags().tagdb().getItems(tag);
+ wassert(actual(packages.empty()).isfalse());
+ /* They should at least contain 'debtags' */
+ wassert(actual(p <= packages).istrue());
+
+ //c.debtags().getTags(""); // XXX HACK AWW!
+ });
+
+ add_method("empty", []() {
+ // If there is no data, Debtags should work as an empty collection
+ EnvOverride eo("DEBTAGS_TAGS", "./empty/notags");
+ Debtags empty;
+
+ wassert(actual(empty.begin() == empty.end()).istrue());
+ wassert(actual(empty.timestamp()) == 0);
+ wassert(actual(empty.hasData()).isfalse());
+
+ set<std::string> res = empty.getTagsOfItem("apt");
+ wassert(actual(res.empty()).istrue());
+ // TODO: currently does not compile because of a bug in tagcoll
+ //res = empty.getTagsOfItems(wibble::singleton(string("apt")));
+ //assert(res.empty());
+
+ res = empty.getAllTags();
+ wassert(actual(res.empty()).istrue());
+ });
+ }
+} tests("debtags");
+
+}
diff --git a/ept/debtags/debtags.test.h b/ept/debtags/debtags.test.h
deleted file mode 100644
index 8376a9d..0000000
--- a/ept/debtags/debtags.test.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*-
-/**
- * @file
- * @author Enrico Zini (enrico) <enrico@enricozini.org>
- */
-
-/*
- * Test for the Debtags data provider
- *
- * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <ept/debtags/debtags.h>
-#include <wibble/operators.h>
-
-#include <ept/test.h>
-#include <cstdio>
-
-#ifndef EPT_DEBTAGS_TESTH
-#define EPT_DEBTAGS_TESTH
-
-using namespace tagcoll;
-using namespace std;
-using namespace ept;
-using namespace ept::debtags;
-using namespace wibble::operators;
-
-#define testfile TEST_ENV_DIR "debtags/package-tags"
-
-struct TestDebtags : DebtagsTestEnvironment
-{
- TestDebtags() {}
-
- Test _1()
- {
- EnvOverride eo("DEBTAGS_TAGS", testfile);
- Debtags debtags;
- for (Debtags::const_iterator i = debtags.begin(); i != debtags.end(); ++i)
- {
- *i;
- i->first;
- i->second;
- }
- }
-
- Test _2()
- {
- EnvOverride eo("DEBTAGS_TAGS", testfile);
- Debtags debtags;
- string p("debtags");
- std::set<std::string> tags = debtags.getTagsOfItem(p);
- assert( !tags.empty() );
-
-#if 0
- for ( std::set< Tag >::iterator i = tags.begin(); i != tags.end(); ++ i ) {
- std::cerr << i->id() << ": " << i->fullname() << std::endl;
- }
- std::cerr << "---" << std::endl;
- Tag t = voc().tagByName( "interface::commandline" );
- std::cerr << t.id() << ": " << t.fullname() << std::endl;
-#endif
-
- assert_eq( tags.size(), 8u );
- assert( tags.find("devel::buildtools") != tags.end() );
- assert( tags.find("implemented-in::c++") != tags.end() );
- assert( tags.find("interface::commandline") != tags.end() );
- assert( tags.find("role::program") != tags.end() );
- assert( tags.find("scope::application") != tags.end() );
- assert( tags.find("suite::debian") != tags.end() );
- assert( tags.find("use::searching") != tags.end() );
- assert( tags.find("works-with::software:package") != tags.end() );
-}
-
- Test _3()
- {
- using namespace std;
- EnvOverride eo("DEBTAGS_TAGS", testfile);
- Debtags debtags;
-
- /* Get the 'debtags' package */
- string p("debtags");
-
- /* Get its tags */
- std::set<std::string> tags = debtags.getTagsOfItem(p);
- assert(!tags.empty());
-
- /*
- cerr << "Intersection size: " << endl;
- using namespace wibble::operators;
- std::set<Tag>::const_iterator dbgi = tags.begin();
- cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl;
- std::set<int> dbgres = debtags.tagdb().getItemsHavingTag(dbgi->id());
- std::set<Package> dbgpres = debtags.getItemsHavingTag(*dbgi);
- cerr << " #pkgs " << dbgres.size() << " == " << dbgpres.size() << endl;
- cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl;
- cerr << " "; ppset(dbgpres); cerr << endl;
- cerr << " "; piset(dbgres); cerr << endl;
- for (++dbgi ; dbgi != tags.end(); ++dbgi)
- {
- cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl;
- std::set<Package> dbgpkgs = debtags.getItemsHavingTag(*dbgi);
- std::set<int> dbgids = debtags.tagdb().getItemsHavingTag(dbgi->id());
- cerr << " "; ppset(dbgpkgs); cerr << endl;
- cerr << " "; piset(dbgids); cerr << endl;
- cerr << " #pkgs " << dbgpkgs.size() << " == " << dbgids.size() << endl;
- dbgres &= dbgids;
- dbgpres &= dbgpkgs;
- cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl;
- }
- cerr << " " << dbgres.size() << endl << "Results: " << endl;
- for (std::set<int>::const_iterator i = dbgres.begin(); i != dbgres.end(); ++i)
- cerr << " " << *i << endl;
- */
-
-
-// cerr << "Tags of debtags: ";
-// for (std::set<Tag>::const_iterator i = tags.begin(); i != tags.end(); ++i)
-// {
-// cerr << " " + i->fullname() << endl;
-// std::set<Package> packages = debtags.getItemsHavingTag(*i);
-// for (std::set<Package>::const_iterator p = packages.begin();
-// p != packages.end(); ++p)
-// cerr << " PKG " << p->name() << endl;
-// }
-// cerr << endl;
-
- /* Get the items for the tagset of 'debtags' */
- std::set<string> packages = debtags.getItemsHavingTags(tags);
- //cerr << packages.size() << endl;
- assert(!packages.empty());
- /*
- for ( std::set< Package >::iterator i = packages.begin(); i != packages.end(); ++ i )
- std::cerr << i->name() << std::endl;
- std::cerr << "---" << std::endl;
- std::cerr << p.name() << std::endl;
- */
- /* They should at least contain 'debtags' */
- assert( p <= packages );
-
- /* Get one of the tags of 'debtags' */
- std::string tag = *tags.begin();
-
- /* Get its items */
- {
- /* Need this workaround until I figure out how to tell the new GCC
- * that TagDB is a TDBReadonlyDiskIndex and should behave as such
- */
- std::set<std::string> ts;
- ts.insert(tag);
- packages = debtags.getItemsHavingTags(ts);
- }
- //packages = c.debtags().tagdb().getItems(tag);
- assert(!packages.empty());
- /* They should at least contain 'debtags' */
- assert( p <= packages );
-
- //c.debtags().getTags(""); // XXX HACK AWW!
-}
-
- // If there is no data, Debtags should work as an empty collection
- Test _4()
- {
- EnvOverride eo("DEBTAGS_TAGS", "./empty/notags");
- Debtags empty;
-
- assert(empty.begin() == empty.end());
- assert_eq(empty.timestamp(), 0);
- assert(!empty.hasData());
-
- set<std::string> res = empty.getTagsOfItem("apt");
- assert(res.empty());
- // TODO: currently does not compile because of a bug in tagcoll
- //res = empty.getTagsOfItems(wibble::singleton(string("apt")));
- //assert(res.empty());
-
- res = empty.getAllTags();
- assert(res.empty());
-}
-
-};
-
-#endif
diff --git a/ept/debtags/vocabulary-test.cc b/ept/debtags/vocabulary-test.cc
new file mode 100644
index 0000000..51f46f9
--- /dev/null
+++ b/ept/debtags/vocabulary-test.cc
@@ -0,0 +1,195 @@
+#include "ept/test.h"
+#include "vocabulary.h"
+#include "coll/set.h"
+#include "ept/test.h"
+
+using namespace std;
+using namespace tagcoll::utils;
+using namespace ept::debtags;
+using namespace ept::tests;
+
+#define testfile "debtags/vocabulary"
+
+namespace {
+
+class Tests : public TestCase
+{
+ using TestCase::TestCase;
+
+ void register_tests() override
+ {
+ add_method("load", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags; // this will throw if it failed to load
+ });
+
+ add_method("has_facet", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+ assert_true( tags.hasFacet( "works-with" ) );
+ assert_true( !tags.hasFacet( "blah" ) );
+ });
+
+ add_method("has_tag", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+ assert_true( tags.hasTag( "works-with::people" ) );
+ assert_true( !tags.hasTag( "works-with::foobar" ) );
+ });
+
+ add_method("tagdata", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+ const voc::TagData *people = tags.tagData( "works-with::people" ),
+ *foobar = tags.tagData( "works-with::foobar" ),
+ *blahg = tags.tagData( "works-with::blahg" ),
+ *text = tags.tagData( "works-with::text" ),
+ *people2 = tags.tagData( "works-with::people" );
+ assert_true( people != foobar );
+ assert_true( people != text );
+ assert_true( people != blahg );
+ assert_true( foobar == blahg );
+ assert_true( foobar == foobar );
+ assert_true( people == people2 );
+ assert_true( people == people );
+ });
+
+ add_method("tags", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+ std::string a = "works-with::people",
+ b = "works-with::foobar";
+ std::set<std::string> s = tags.tags(),
+ f = tags.tags( "works-with" ),
+ n = tags.tags( "nonsense" );
+ assert_true( set_contains(s, a) );
+ assert_true( set_contains(f, a) );
+ assert_true( set_contains(s, f) );
+ assert_true( !set_contains(s, b) );
+ assert_true( !set_contains(f, b) );
+ assert_true( n.empty() );
+ });
+
+ add_method("facetdata", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ const voc::FacetData* f = tags.facetData( "works-with" );
+ assert_true(f);
+ wassert(actual(f->name) == "works-with");
+
+ const voc::TagData* t = tags.tagData( "works-with::people" );
+ assert_true(t);
+ wassert(actual(t->name) == "works-with::people");
+ });
+
+ add_method("facettags", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ const voc::FacetData* f = tags.facetData( "works-with" );
+ std::set<std::string> x = tags.tags( "works-with" );
+ assert_true( x == f->tags() );
+ });
+
+ add_method("missing_facet", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ const voc::FacetData* f = tags.facetData( "does-not-work-with" );
+ assert_true(!f);
+ });
+
+ add_method("missing_facet1", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ const voc::FacetData* f = tags.facetData( "legacy" );
+ assert_true(f);
+ wassert(actual(f->shortDescription()) == "");
+ wassert(actual(f->longDescription()) == "");
+ //wassert(actual(f.shortDescription( "weehee" )) == "weehee");
+ });
+
+ add_method("one_letter_tag", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ // assert_true that one-character tag names are parsed correctly
+ assert_true( tags.hasTag( "implemented-in::c" ) );
+ });
+
+ add_method("iterate_facets", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ // assert_true that all facets are somehow working
+ std::set<std::string> facets = tags.facets();
+
+ for (std::set<std::string>::const_iterator i = facets.begin();
+ i != facets.end(); i++)
+ {
+ const voc::FacetData* f = tags.facetData(*i);
+ assert_true(f);
+ }
+ });
+
+ add_method("iterate_tags", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary voc;
+
+ // assert_true that all tags are somehow working
+ std::set<std::string> tags = voc.tags();
+ for (std::set<std::string>::const_iterator i = tags.begin();
+ i != tags.end(); i++)
+ {
+ const voc::TagData* t = voc.tagData(*i);
+ assert_true(t);
+ }
+ });
+
+ add_method("first_last", []() {
+ // Check for correctness of the first and last tag in the vocabulary
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ const voc::TagData* first = tags.tagData("accessibility::TODO");
+ assert_true(first);
+ wassert(actual(first->name) == string("accessibility::TODO"));
+ wassert(actual(first->shortDescription()) == string("Need an extra tag"));
+
+ const voc::TagData* last = tags.tagData("x11::xserver");
+ assert_true(last);
+ wassert(actual(last->name) == string("x11::xserver"));
+ wassert(actual(last->shortDescription()) == string("X Server"));
+ });
+
+ add_method("get_all_tags", []() {
+ EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
+ Vocabulary tags;
+
+ // check that we're seeing all the tags for a facet
+ std::set<std::string> t = tags.tags("accessibility");
+ wassert(actual(t.size()) == 10u);
+
+ t = tags.tags("works-with-format");
+ wassert(actual(t.size()) == 33u);
+ });
+
+ add_method("empty", []() {
+ // If there is no data, Vocabulary should work as an empty vocabulary
+ EnvOverride eo("DEBTAGS_VOCABULARY", "./empty/novocabularyhere");
+ Vocabulary empty;
+
+ assert_true(!empty.hasData());
+
+ set<std::string> facets = empty.facets();
+ wassert(actual(facets.size()) == 0u);
+
+ set<std::string> tags = empty.tags();
+ wassert(actual(tags.size()) == 0u);
+ });
+ }
+} tests("debtags_vocabulary");
+
+}
diff --git a/ept/debtags/vocabulary.test.h b/ept/debtags/vocabulary.test.h
deleted file mode 100644
index 4d698ea..0000000
--- a/ept/debtags/vocabulary.test.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Tag vocabulary access
- *
- * Copyright (C) 2003--2007 Enrico Zini <enrico@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <wibble/test.h>
-#include <ept/debtags/vocabulary.h>
-#include <ept/debtags/coll/set.h>
-#include "ept/test.h"
-
-using namespace std;
-using namespace tagcoll::utils;
-using namespace ept::debtags;
-
-#define testfile TEST_ENV_DIR "debtags/vocabulary"
-
-
-struct TestVocabulary : DebtagsTestEnvironment
-{
- Test _1()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags; // this will throw if it failed to load
-}
-
- Test _2()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
- assert( tags.hasFacet( "works-with" ) );
- assert( !tags.hasFacet( "blah" ) );
-}
-
- Test _3()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
- assert( tags.hasTag( "works-with::people" ) );
- assert( !tags.hasTag( "works-with::foobar" ) );
-}
-
- Test _4()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
- const voc::TagData *people = tags.tagData( "works-with::people" ),
- *foobar = tags.tagData( "works-with::foobar" ),
- *blahg = tags.tagData( "works-with::blahg" ),
- *text = tags.tagData( "works-with::text" ),
- *people2 = tags.tagData( "works-with::people" );
- assert( people != foobar );
- assert( people != text );
- assert( people != blahg );
- assert( foobar == blahg );
- assert( foobar == foobar );
- assert( people == people2 );
- assert( people == people );
-}
-
- Test _5()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
- std::string a = "works-with::people",
- b = "works-with::foobar";
- std::set<std::string> s = tags.tags(),
- f = tags.tags( "works-with" ),
- n = tags.tags( "nonsense" );
- assert( set_contains(s, a) );
- assert( set_contains(f, a) );
- assert( set_contains(s, f) );
- assert( !set_contains(s, b) );
- assert( !set_contains(f, b) );
- assert( n.empty() );
-}
-
- Test _6()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- const voc::FacetData* f = tags.facetData( "works-with" );
- assert(f);
- assert_eq(f->name, "works-with");
-
- const voc::TagData* t = tags.tagData( "works-with::people" );
- assert(t);
- assert_eq(t->name, "works-with::people");
-}
-
- Test _7()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- const voc::FacetData* f = tags.facetData( "works-with" );
- std::set<std::string> x = tags.tags( "works-with" );
- assert( x == f->tags() );
-}
-
- Test _8()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- const voc::FacetData* f = tags.facetData( "does-not-work-with" );
- assert(!f);
-}
-
- Test _9()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- const voc::FacetData* f = tags.facetData( "legacy" );
- assert(f);
- assert_eq(f->shortDescription(), "");
- assert_eq(f->longDescription(), "");
- //assert_eq(f.shortDescription( "weehee" ), "weehee");
-}
-
- Test _10()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- // assert that one-character tag names are parsed correctly
- assert( tags.hasTag( "implemented-in::c" ) );
-}
-
- Test _11()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- // assert that all facets are somehow working
- std::set<std::string> facets = tags.facets();
-
- for (std::set<std::string>::const_iterator i = facets.begin();
- i != facets.end(); i++)
- {
- const voc::FacetData* f = tags.facetData(*i);
- assert(f);
- }
-}
-
- Test _12()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary voc;
-
- // assert that all tags are somehow working
- std::set<std::string> tags = voc.tags();
- for (std::set<std::string>::const_iterator i = tags.begin();
- i != tags.end(); i++)
- {
- const voc::TagData* t = voc.tagData(*i);
- assert(t);
- }
-}
-
-// Check for correctness of the first and last tag in the vocabulary
- Test _13()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- const voc::TagData* first = tags.tagData("accessibility::TODO");
- assert(first);
- assert_eq(first->name, string("accessibility::TODO"));
- assert_eq(first->shortDescription(), string("Need an extra tag"));
-
- const voc::TagData* last = tags.tagData("x11::xserver");
- assert(last);
- assert_eq(last->name, string("x11::xserver"));
- assert_eq(last->shortDescription(), string("X Server"));
-}
-
- Test _14()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", testfile);
- Vocabulary tags;
-
- // check that we're seeing all the tags for a facet
- std::set<std::string> t = tags.tags("accessibility");
- assert_eq(t.size(), 10u);
-
- t = tags.tags("works-with-format");
- assert_eq(t.size(), 33u);
-}
-
-// If there is no data, Vocabulary should work as an empty vocabulary
- Test _15()
-{
- EnvOverride eo("DEBTAGS_VOCABULARY", "./empty/novocabularyhere");
- Vocabulary empty;
-
- assert(!empty.hasData());
-
- set<std::string> facets = empty.facets();
- assert_eq(facets.size(), 0u);
-
- set<std::string> tags = empty.tags();
- assert_eq(tags.size(), 0u);
-}
-
-};
diff --git a/ept/test-main.h b/ept/test-main.h
deleted file mode 100644
index 7b2afbc..0000000
--- a/ept/test-main.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// -*- C++ -*-
-#include <unistd.h>
-#include <sys/wait.h>
-
-struct Main {
-
- int suite, test;
- int status[2];
- int confirm[2];
- FILE *f_confirm, *f_status;
- pid_t pid;
- int argc;
- char **argv;
- pid_t finished;
- int status_code;
- int test_ok;
-
- int suite_ok, suite_failed;
- int total_ok, total_failed;
-
- int announced_suite;
- std::string current;
-
- RunAll all;
-
- Main() : suite(0), test(0) {
- suite_ok = suite_failed = 0;
- total_ok = total_failed = 0;
- test_ok = 0;
- announced_suite = -1;
- }
-
- void child() {
- close( status[0] );
- close( confirm[1] );
- all.status = fdopen( status[1], "w" );
- all.confirm = fdopen( confirm[0], "r" );
- if ( argc > 1 ) {
- RunSuite *s = all.findSuite( argv[1] );
- if (!s) {
- std::cerr << "No such suite " << argv[1] << std::endl;
- // todo dump possible suites?
- exit(250);
- }
- all.runSuite( *s, test, 0, 1 );
- }
- if ( argc == 1 ) {
- all.runFrom( suite, test );
- }
- fprintf( all.status, "done\n" );
- exit( 0 );
- }
-
- void testDied()
- {
- /* std::cerr << "test died: " << test << "/"
- << suites[suite].testCount << std::endl; */
- if ( WIFEXITED( status_code ) ) {
- if ( WEXITSTATUS( status_code ) == 250 )
- exit( 3 );
- if ( WEXITSTATUS( status_code ) == 0 )
- return;
- }
- std::cout << "failed test: "<< current;
- if ( WIFEXITED( status_code ) )
- std::cout << " (exit status " << WEXITSTATUS( status_code ) << ")";
- if ( WIFSIGNALED( status_code ) )
- std::cout << " (caught signal " << WTERMSIG( status_code ) << ")";
- std::cout << std::endl;
- // re-announce the suite
- announced_suite --;
- ++ test; // continue with next test
- test_ok = 0;
- suite_failed ++;
- }
-
- void processStatus( const char *line ) {
- if ( std::string("done") == line ) { // finished
- finished = waitpid( pid, &status_code, 0 );
- assert_eq( pid, finished );
- assert( WIFEXITED( status_code ) );
- assert_eq( WEXITSTATUS( status_code ), 0 );
- std::cout << "overall " << total_ok << "/"
- << total_ok + total_failed
- << " ok" << std::endl;
- exit( total_failed == 0 ? 0 : 1 );
- }
-
- if ( test_ok ) {
- /* std::cerr << "test ok: " << test << "/"
- << suites[suite].testCount << std::endl; */
- std::cout << "." << std::flush;
- suite_ok ++;
- ++ test;
- test_ok = 0;
- }
-
- if ( line[0] == 's' ) {
- if ( line[2] == 'd' ) {
- std::cout << " " << suite_ok << "/" << suite_ok + suite_failed
- << " ok" << std::endl;
- ++ suite; test = 0;
- assert( !test_ok );
- total_ok += suite_ok;
- total_failed += suite_failed;
- suite_ok = suite_failed = 0;
- }
- if ( line[2] == 's' ) {
- if ( announced_suite < suite ) {
- std::cout << line + 5 << ": " << std::flush;
- announced_suite = suite;
- }
- }
- }
- if ( line[0] == 't' ) {
- if ( line[2] == 'd' ) {
- fprintf( f_confirm, "ack\n" );
- fflush( f_confirm );
- test_ok = 1;
- }
- if ( line[2] == 's' ) {
- fprintf( f_confirm, "ack\n" );
- fflush( f_confirm );
- current = line + 5;
- }
- }
- }
-
- void parent() {
- close( status[1] );
- close( confirm[0] );
- f_status = fdopen( status[0], "r" );
- f_confirm = fdopen( confirm[1], "w" );
- char *line = 0;
- size_t n;
-
- while ( true ) {
- if ( getline( &line, &n, f_status ) < 0 ) {
- finished = waitpid( pid, &status_code, 0 );
- if ( finished < 0 ) {
- perror( "waitpid failed" );
- exit( 5 );
- }
- assert_eq( pid, finished );
- testDied();
- /* std::cerr << "child will be reforked at: "
- << suite << " " << test << std::endl; */
- return;
- } else {
- // std::cerr << "reading pipe: " << line;
- line[ strlen( line ) - 1 ] = 0;
- processStatus( line );
- free( line );
- }
- line = 0;
- }
- }
-
- int main( int _argc, char **_argv )
- {
- argc = _argc;
- argv = _argv;
-
- all.suiteCount = sizeof(suites)/sizeof(RunSuite);
- all.suites = suites;
-
- while (true) {
- if ( pipe( status ) )
- return 1;
- if ( pipe( confirm ) )
- return 1;
- pid = fork();
- if ( pid < 0 )
- return 2;
- if ( pid == 0 ) { // child
- child();
- } else {
- parent();
- }
- }
- }
-};
-
-int main( int argc, char **argv ) {
- return Main().main( argc, argv );
-}
diff --git a/ept/test-runner.h b/ept/test-runner.h
deleted file mode 100644
index 8fe4d12..0000000
--- a/ept/test-runner.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <unistd.h>
-
-#define RUN(x, y) x().y()
-
-struct RunTest {
- const char *name;
- void (*run)();
-};
-
-struct RunSuite {
- const char *name;
- RunTest *tests;
- int testCount;
-};
-
-struct RunAll {
- RunSuite *suites;
- int suiteCount;
- FILE *status, *confirm;
-
- RunSuite *findSuite( std::string name ) {
- for ( int i = 0; i < suiteCount; ++i )
- if ( suites[i].name == name )
- return suites + i;
- return 0;
- }
-
- void waitForAck() {
- size_t n = 0; char *line = 0;
- size_t read = getline( &line, &n, confirm );
- assert_eq( read, 4 );
- assert_eq( std::string( "ack\n" ), line );
- free( line );
- }
-
- void runSuite( RunSuite &s, int fromTest, int suite, int suiteCount )
- {
- fprintf( status, "s/s: (%d/%d) %s\n", suite + 1, suiteCount, s.name );
- for ( int i = fromTest; i < s.testCount; ++i ) {
- fprintf( status, "t/s: (%d/%d) %s\n", i, s.testCount,
- s.tests[i].name );
- fflush( status );
- waitForAck();
- s.tests[i].run();
- fprintf( status, "t/d: %s\n", s.tests[i].name );
- fflush( status );
- waitForAck();
- // exit( 0 ); // TODO make this optional; safety vs
- // performance tradeoff
- }
- fprintf( status, "s/d: %s\n", s.name );
- }
-
- void runFrom( int suite, int test )
- {
- for ( int i = suite; i < suiteCount; ++i ) {
- assert( suite <= suiteCount );
- runSuite( suites[i], test, i, suiteCount );
- test = 0;
- }
- }
-};
-
diff --git a/ept/test.h b/ept/test.h
index fc29ed6..e0b8d20 100644
--- a/ept/test.h
+++ b/ept/test.h
@@ -1,8 +1,8 @@
-//#include <ept/core/apt.h>
-#include <ept/config.h>
-
-#include <wibble/test.h>
+#ifndef EPT_TEST_H
+#define EPT_TEST_H
+#include <ept/utils/tests.h>
+#include <ept/config.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/error.h>
@@ -13,29 +13,6 @@
#include <apt-pkg/init.h>
#include <cstdlib>
-
-#ifndef EPT_TEST_H
-#define EPT_TEST_H
-
-struct AptTestEnvironment {
- //ept::core::AptDatabase db;
- AptTestEnvironment() {
- pkgInitConfig (*_config);
- _config->Set("Initialized", 1);
- _config->Set("Dir", TEST_ENV_DIR);
- _config->Set("Dir::Cache", "cache");
- _config->Set("Dir::State", "state");
- _config->Set("Dir::Etc", "etc");
- _config->Set("Dir::Etc::sourcelist", "sources.list");
- _config->Set("Dir::State::status", TEST_ENV_DIR "dpkg-status");
- pkgInitSystem (*_config, _system);
- }
-};
-
-struct DebtagsTestEnvironment : AptTestEnvironment {
- DebtagsTestEnvironment() {}
-};
-
struct EnvOverride
{
const char* name;
diff --git a/ept/utils/tests.h b/ept/utils/tests.h
index 6622cae..3b00a14 100644
--- a/ept/utils/tests.h
+++ b/ept/utils/tests.h
@@ -350,6 +350,12 @@ inline ActualFunction actual_function(std::function<void()> actual) { return Act
throw TestFailed(e, __FILE__, __LINE__, #__VA_ARGS__, ept_test_location_info); \
} } while(0)
+/// Shortcut to check that a given expression returns true
+#define wassert_true(...) wassert(actual(__VA_ARGS__).istrue())
+
+/// Shortcut to check that a given expression returns false
+#define wassert_false(...) wassert(actual(__VA_ARGS__).isfalse())
+
/**
* Call a function returning its result, and raising TestFailed with the
* appropriate backtrace information if it threw an exception.
diff --git a/run-check b/run-check
new file mode 100755
index 0000000..ea05d69
--- /dev/null
+++ b/run-check
@@ -0,0 +1,59 @@
+#!/bin/sh -e
+
+TOP_SRCDIR=$(readlink -f $(dirname "$0"))
+CMD=$(readlink -f "$1")
+
+## Set up the test environment
+datadir="${TOP_SRCDIR}/ept/test-data"
+TESTDIR="`mktemp -d`"
+cd "$TESTDIR"
+
+## Clean up the test environment at exit unless asked otherwise
+cleanup() {
+ test -z "$PRESERVE" && rm -rf "$TESTDIR"
+}
+trap cleanup EXIT
+
+ARCH=$(dpkg --print-architecture)
+listfile=wherever_debian_._Packages
+mkdir -p etc state/lists/partial cache debtags cache/archives/partial desktop
+sed -e s,i386,${ARCH}, < ${datadir}/packagelist > state/lists/${listfile}
+cp -a ${datadir}/etc/sources.list etc/
+sed -e s,i386,${ARCH}, < ${datadir}/dpkg-status > dpkg-status
+cp -a ${datadir}/desktop/*.desktop desktop/
+cp ${datadir}/debtags/package-tags debtags/package-tags
+cp ${datadir}/debtags/vocabulary debtags/vocabulary
+mkdir -p debtags/empty
+mkdir -p debtags/user
+mkdir -p xapian/
+
+# Try to debug the libtool executable, if present
+DIR=`dirname $CMD`
+BASE=`basename $CMD`
+if [ ! -z "$DEBUGGER" ]
+then
+ echo "Running $DEBUGGER $CMD $ARGS"
+ RES=0
+ if ! $DEBUGGER $CMD $ARGS
+ then
+ RES=$?
+ echo "Failed with result $RES"
+ fi
+else
+ echo "Running $CMD $ARGS"
+ RES=0
+ if ! $CMD $ARGS
+ then
+ RES=$?
+ echo "Failed with result $RES"
+ fi
+fi
+
+if [ ! -z "$PAUSE" ]
+then
+ echo "Post-test inspection requested."
+ echo "Exit this shell to cleanup the test environment."
+ bash
+fi
+
+exit $RES