--- libtut-0.0.20070706.orig/debian/libtut-dev.install +++ libtut-0.0.20070706/debian/libtut-dev.install @@ -0,0 +1,4 @@ +*.h usr/include +tut/* usr/include/tut +debian/libtut.pc usr/share/pkgconfig +docs/* usr/share/doc/libtut-dev/html --- libtut-0.0.20070706.orig/debian/copyright +++ libtut-0.0.20070706/debian/copyright @@ -0,0 +1,33 @@ +This package was debianized by martin f. krafft on +Wed, 11 May 2005 21:46:57 +0200 + +It was downloaded from http://tut-framework.sourceforge.net + +Upstream Author: Vladimir (dozen) Dyuzhev + +Copyright: 2002-2006 Vladimir Dozen. +Packaging Copyright © 2005-2006 martin f. krafft + Copyright © 2008 César Gómez Martín + +Licence: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. --- libtut-0.0.20070706.orig/debian/changelog +++ libtut-0.0.20070706/debian/changelog @@ -0,0 +1,57 @@ +libtut (0.0.20070706-1) unstable; urgency=low + + * New maintainer. (Closes: #446162) + * New upstream release (2007-07-06). + * Removed unzip from Build-Depends and debian/rules + * Standard-Version 3.7.2--> 3.7.3 + * Added Homepage field to debian/control + * Patches have been recreated to fit the new upstream version + + -- César Gómez Martín Tue, 05 Feb 2008 13:44:23 +0100 + +libtut (0.0.20060329-1) unstable; urgency=low + + * New upstream release. + + -- martin f. krafft Fri, 9 Jun 2006 16:24:29 +0200 + +libtut (0.0.20040326-6) unstable; urgency=low + + * Removed suggestion for libtut-doc, which does not exist. + + -- martin f. krafft Sat, 14 May 2005 20:04:33 +0200 + +libtut (0.0.20040326-5) unstable; urgency=low + + * Fixed missing homepage link in README.docs. + + -- martin f. krafft Sat, 14 May 2005 01:17:43 +0200 + +libtut (0.0.20040326-4) unstable; urgency=low + + * Added documentation (from webpage). + + -- martin f. krafft Sat, 14 May 2005 01:05:24 +0200 + +libtut (0.0.20040326-3) unstable; urgency=low + + * Added README.gcc-3.4 with notes for users of gcc 3.4. + * pkg-config file now goes to /usr/share/pkgconfig, as supported by newer + pkg-config libraries. + * Added versioned suggestion on pkg-config 0.16.0-1. + + -- martin f. krafft Fri, 13 May 2005 14:03:39 +0200 + +libtut (0.0.20040326-2) unstable; urgency=low + + * Fixed Makefiles in examples. (thanks to Petri Latvala for "insisting" + I fix this, and subsequent testing.) + + -- martin f. krafft Wed, 11 May 2005 22:30:00 +0200 + +libtut (0.0.20040326-1) unstable; urgency=low + + * Initial release (closes: Bug#307774). + + -- martin f. krafft Wed, 11 May 2005 21:44:44 +0200 + --- libtut-0.0.20070706.orig/debian/control +++ libtut-0.0.20070706/debian/control @@ -0,0 +1,22 @@ +Source: libtut +Section: libs +Priority: optional +Maintainer: César Gómez Martín +Build-Depends: debhelper (>> 5), dpatch +Standards-Version: 3.7.3 +Homepage: http://tut-framework.sourceforge.net/ + +Package: libtut-dev +Section: libdevel +Architecture: all +Suggests: pkg-config (>= 0.16.0-1) +Description: elegant C++ unit test framework + TUT is a unit test framework for C++, written in pure C++. It makes use of + C++ templates to reduce the responsibilities of the user and provide an + intuitive and easy-to-use interface. Unlike other test unit frameworks for + C++, TUT doesn't use macros, since their usage conceals actual implementation + and (what's worse) can interfere with client application. + . + TUT completely fits into a single header file. No library compilation is + required, thus a lot of portability problems are avoided and integration with + client code is very simple. --- libtut-0.0.20070706.orig/debian/libtut.pc +++ libtut-0.0.20070706/debian/libtut.pc @@ -0,0 +1,7 @@ +prefix=/usr +includedir=${prefix}/include + +Name: libtut +Description: TUT unit testing framework for C++ +Version: 2006.03.29 +Cflags: -I${includedir} --- libtut-0.0.20070706.orig/debian/libtut-dev.docs +++ libtut-0.0.20070706/debian/libtut-dev.docs @@ -0,0 +1,2 @@ +debian/README.gcc-3.4-and-up +README --- libtut-0.0.20070706.orig/debian/libtut-dev.examples +++ libtut-0.0.20070706/debian/libtut-dev.examples @@ -0,0 +1,2 @@ +examples/* +Makefile.gcc-unix --- libtut-0.0.20070706.orig/debian/patches/90-docs.dpatch +++ libtut-0.0.20070706/debian/patches/90-docs.dpatch @@ -0,0 +1,2104 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 90-docs.dpatch by martin f. krafft +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Add documentation from webpage. + +@DPATCH@ +diff -urNad libtut-0.0.20060329~/docs/Makefile libtut-0.0.20060329/docs/Makefile +--- libtut-0.0.20060329~/docs/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ libtut-0.0.20060329/docs/Makefile 2006-06-09 16:53:46.231411997 +0200 +@@ -0,0 +1,6 @@ ++.PHONY: get ++get: ++ for i in howto example design faq; do \ ++ wget -O $$i.html http://tut-framework.sourceforge.net/$$i/; \ ++ done ++ sed -i -e "\$$s,> .*,> $$(date)," README.docs +diff -urNad libtut-0.0.20060329~/docs/README.docs libtut-0.0.20060329/docs/README.docs +--- libtut-0.0.20060329~/docs/README.docs 1970-01-01 01:00:00.000000000 +0100 ++++ libtut-0.0.20060329/docs/README.docs 2006-06-09 16:53:50.343609186 +0200 +@@ -0,0 +1,9 @@ ++libtut documentation README ++--------------------------- ++ ++The HTML files you can find in this directory have been pulled from the TUT ++homepage[0] at the point in time listed below. ++ ++0. http://tut-framework.sourceforge.net ++ ++ -- martin f. krafft Fri Jun 9 16:53:50 CEST 2006 +diff -urNad libtut-0.0.20060329~/docs/design.html libtut-0.0.20060329/docs/design.html +--- libtut-0.0.20060329~/docs/design.html 1970-01-01 01:00:00.000000000 +0100 ++++ libtut-0.0.20060329/docs/design.html 2006-06-09 16:53:49.667576768 +0200 +@@ -0,0 +1,479 @@ ++ ++ ++ ++ ++TUT Design - TUT: C++ Unit Test Framework ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++
++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++
++ ++
++ ++
++
++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

Documentation

++
    ++
  • TUT How-To
    minimum steps to make TUT work for you

  • ++
  • TUT Design
    what's hidden under the hood of tut.h, and why things are such as they ++ are

  • ++
  • TUT Usage Example
    it's better to see once...

  • ++
  • TUT As Is
    complete source of TUT

  • ++
++

Distribution

++ ++

Support

++ ++
++ ++
++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

TUT Design

++

In this document I attempt to explain the decisions made while developing ++ TUT.

++ ++

Requirements

++ ++

One day I ran into need of unit test framework for C++. So, I've made a small research ++ and discovered C++Unit, boost::test and a bunch of similar libraries.. Though ++ they were usable, I was not satisfied with the approach they offered; so I ++ designed my own variant of unit test framework based on the following ++ restrictions:

++ ++
    ++
  • No C-style macros
  • ++
  • No manual registration for test groups and methods
  • ++
  • No libraries of any kind
  • ++
  • Neutrality to user interface
  • ++
  • No Javisms
  • ++
++ ++

C-style macros and what's wrong with them

++ ++

Usually C++ Unit test frameworks define a lot of macroses to achieve the goals ++ other languages have as built-in features: for example, Java is able to show you ++ the whole exception stack; and C++ cannot. So, to achieve the same (or similar) ++ results, C++ frameworks often declare a macro to catch any exception and trace ++ __FILE__ and __LINE__ variables.

++ ++

The problem is that it turns the C++ code into something that is hard to read, where ++ "hard to read" actually means "hard to maintain".

++ ++

Macros don't recognize namespace borders, so a simple macro can expand in the user ++ code into something unexpected. To avoid this, we have to give macros unique ++ prefixes, and this, in turn, reduces code readability even more.

++ ++

From bad to worse, C-style macros can't handle modern C++ templates, so comma ++ separated template arguments will break the macro, since preprocessor will ++ handle the template as two arguments (separated by the comma used in the ++ template) to this macro.

++ ++

And the final contra for macros is that even if used they cannot achieve the same ++ usability level as the native language tools; for example, macros cannot ++ generate a full stack trace (at least, in a platform-independent manner). So it ++ looks like we loose readability and get almost nothing for this.

++ ++

See also Bjarne Stroustrup notices about macros harmness: ++ So, ++ what's wrong with using macros?

++ ++

Manual registration and why it annoys me

++ ++

In JUnit (Java-based Unit Tests framework) reflection is used to recognize ++ user-written test methods. C++ has no reflection or similar mechanism, so user ++ must somehow tell the framework that "this, this and that" methods should be ++ considered as test methods, and others are just helpers for them.

++ ++

The same can be said about test groups, which have to be registered in test runner ++ object.

++ ++

Again, most C++ frameworks introduce macros or at least methods to register a ++ freestanding function or method as a test instance. I find writing redundant ++ code rather annoying: I have to write test itself and then I have to write more code ++ to mark that my test is a test. Even more, if I forget to register the method, ++ nothing will warn me or somehow indicate that I have not done what I should.

++ ++

Library and integration problems

++ ++

Most of C++ frameworks require building a library that user must link to test ++ application to be able to run tests. The problem is that various platforms imply ++ different ways for building libraries. One popular C++ framework has more than ++ 60% bugs in their bug database that sound like "cannot build library on platform ++ XXX" or "built library doesn't work on platform YYY".

++ ++

Besides, some platforms has complexities in library memory management (e.g. ++ Win32).

++ ++

User interface

++ ++

Some frameworks provide predefined formatters for output results, for example ++ CSV or XML. This restricts users in test results presentation options. What if a ++ user wants some completely different format? Of course, he can implement his own ++ formatter, but why frameworks provide useless formatters then?

++ ++

The ideal test framework must do only one thing: run tests. Anything beyond that is ++ the responsibility of the user code. Framework provides the test results, and ++ the user code then represents them in any desired form.

++ ++

Javisms

++ ++

Most implementors of C++ test frameworks know about JUnit and inspired by ++ this exciting tool. But, carelessly copying a Java implementation to C++, we can ++ get strange and ugly design.

++ ++

Rather obvious example: JUnit has methods for setting up a test (setUp) and for ++ cleaning after it (tearDown). I know at least two C++ frameworks that have these ++ methods with the same semantics and names. But in C++ the job these methods do is ++ the responsibility of constructor and destructor! In Java we don't have ++ guaranteed destruction, so JUnit authors had to invent their own replacement ++ for it - tearDown(); and it was natural then to introduce constructing ++ counterpart - setUp(). Doing the same in C++ is absolutely redundant ++

++ ++

C++ has its own way of working, and whenever possible, I am going to stay at the C++ ++ roads, and will not repeat Java implementation just because it is really good for ++ Java.

++ ++

Decisions

++ ++

No C-style macros

++ ++

The solution is that simple: just ++ do not use any macros. I personally never needed a macro during ++ development.

++ ++

No manual registration

++ ++

Since C++ has no reflection, the only way to mark a method as a test is to give it a kind ++ of predefined name.

++ ++

There would be a simple solution: create a set of virtual methods in test object base ++ class, and allow user to overwrite them. The code might look like:

++ ++
 struct a_test_group : public test_group { virtual void test1() { ... } virtual
++			void test2() { ... } }; 
++ ++

Unfortunately, this approach has major drawbacks:

++ ++
    ++
  • It scales badly. Consider, we have created 100 virtual test methods in a test ++ group, but user needs 200. How can he achieve that? There is no proper way. ++ Frankly speaking, such a demand will arise rarely (mostly in ++ script-generated tests), but even the possibility of it makes this kind of ++ design seemingly poor.
  • ++ ++
  • There is no way to iterate virtual methods automatically. We ++ would end up writing code that calls test1(), then test2(), and so on, each ++ with its own exception handling and reporting.
  • ++
++ ++

Another possible solution is to substitute reflection with a dynamic loading. ++ User then would write static functions with predefined names, and TUT would use ++ dlsym()/GetProcAddress() to find out the implemented tests.

++ ++

But I rejected the solution due to its platform and library operations ++ dependencies. As I described above, the library operations are quite different ++ on various platform.

++ ++

There was also an idea to have a small parser, that can scan the user code and ++ generate registration procedure. This solution only looks simple; parsing ++ free-standing user code can be a tricky procedure, and might easily overgrow twelve TUTs ++ in complexity.

++ ++

Fortunately, modern C++ compilers already have a tool that can parse the user code ++ and iterate methods. It is compiler template processing engine. To be more ++ precise, it is template specialization technique.

++ ++

The following code iterates all methods named test<N> ranging from n to 0, ++ and takes the address of each:

++ ++
 
++template <class Test,class Group,int n> 
++struct tests_registerer 
++{
++	static void reg(Group& group) 
++	{ 
++		group.reg(n,&Test::template	test<n>); 
++		tests_registerer<Test,Group,n-1>::reg(group); 
++	}
++}; 
++			
++template<class Test,class Group> 
++struct tests_registerer<Test,Group,0> 
++{ 
++	static void reg(Group&){}; 
++};
++... 
++test_registerer<test,group,100>.reg(grp); 
++		
++ ++

This code generates recursive template instantiations until it reaches ++ tests_registerer<Test,Group,0> which has empty specialization. ++ There the recursion stops.

++ ++

The code is suitable for our needs because in the specialization preference is ++ given to the user-written code, not to the generic one. Suppose we have a default ++ method test<N> in our test group, and the user-written specialization ++ for test<1>. So while iterating, compiler will get the address of the ++ default method for all N, except 1, since user has supplied a special version of ++ that method.

++ ++
 
++template<int N> 
++void test() { }; 
++... 
++template<> 
++void test_group::test<1>() { // user code here } 
++		
++ ++

This approach can be regarded as kind of compile-time virtual functions, since ++ the user-written methods replace the default implementation. At the same time, ++ it scales well - one just has to specify another test number upper bound at compile ++ time. The method also allows iteration of methods, keeping code compact.

++ ++

Library

++ ++

Since we dig into the template processing, it is natural to not build any ++ libraries, therefor this problem mostly disappeares. Unfortunately, not ++ completely: our code still needs some central point where it could register ++ itself. But that point (singleton) is so small that it would be an overkill to ++ create library just to put there one single object. Instead, we assume that the ++ user code will contain our singleton somewhere in the main module of test ++ application.

++ ++

User interface. Callbacks.

++ ++

Our code will perform only minimamum set of tasks: TUT shall run tests. But we still ++ need a way to adapt the end-user presentation requirements. For some of users it ++ would be enough to see only failed tests in listing; others would like to see the ++ complete plain-text report; some would prefer to get XML reports, and some would ++ not want to get any reports at all since they draw their test execution log in GUI ++ plugin for an IDE.

++ ++

"Many users" means "many demands", and satisfying all of them is quite a hard task. ++ Attempt to use a kind of silver bullet (like XML) is not the right solution, since ++ user would lack XML parser in his environment, or just would not want to put it into ++ his project due to integration complexities.

++ ++

The decision was made to allow users to form their reports by themselfs. TUT will ++ report an event, and the user code will form some kind of an artefact based on this ++ event.

++ ++

The implementation of this decision is interface tut::callback. The user code ++ creates a callback object, and passes it to the runner. When an appropriate event ++ occures, the test runner invokes callback methods. User code can do anything, ++ from dumping test results to std::cout to drawing 3D images, if desired.

++ ++

STL

++ ++

Initially, there were plans to make TUT traits-based in order not to restrict ++ it with STL only, but have a possibility to use other kinds of strings ++ (TString, CString), containers and intercepted exceptions.

++ ++

In the current version, these plans are not implemented due to relative ++ complexity of the task. For example, the actual set of operations can be quite ++ different for various map implementations and this makes writing generic code ++ much harder.

++ ++

Thus so far TUT is completely STL-based, since STL is the only library existing ++ virtually on every platform.

++
++ ++
++ ++ ++ ++
++ ++
++ ++
++ ++
++ ++ ++ +diff -urNad libtut-0.0.20060329~/docs/example.html libtut-0.0.20060329/docs/example.html +--- libtut-0.0.20060329~/docs/example.html 1970-01-01 01:00:00.000000000 +0100 ++++ libtut-0.0.20060329/docs/example.html 2006-06-09 16:53:48.871538596 +0200 +@@ -0,0 +1,379 @@ ++ ++ ++ ++ ++TUT Usage Example - TUT: C++ Unit Test Framework ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++
++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++
++ ++
++ ++
++
++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

Documentation

++
    ++
  • TUT How-To
    minimum steps to make TUT work for you

  • ++
  • TUT Design
    what's hidden under the hood of tut.h, and why things are such as they ++ are

  • ++
  • TUT Usage Example
    it's better to see once...

  • ++
  • TUT As Is
    complete source of TUT

  • ++
++

Distribution

++ ++

Support

++ ++
++ ++
++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

TUT Usage Example

++
++#include <tut.h>
++#include <set>
++#include <memory>
++
++/**
++ * This example test group tests std::auto_ptr implementation.
++ * Tests are far from full, of course.
++ */
++namespace tut
++{
++  /**
++   * Struct which may contain test data members.
++   * Test object (class that contains test methods)
++   * will inherite from it, so each test method can
++   * access members directly.
++   *
++   * Additionally, for each test, test object is re-created
++   * using defaut constructor. Thus, any prepare work can be put
++   * into default constructor.
++   *
++   * Finally, after each test, test object is destroyed independently
++   * of test result, so any cleanup work should be located in destructor.
++   */
++  struct auto_ptr_data
++  { 
++    /**
++     * Type used to check scope lifetime of auto_ptr object.
++     * Sets extern boolean value into true at constructor, and
++     * to false at destructor.
++     */
++    bool exists;
++    struct existing
++    {
++      bool& s_;
++      existing(bool& s) : s_(s){ s_ = true; };
++      ~existing(){ s_ = false; };
++    };
++  };
++
++  /**
++   * This group of declarations is just to register
++   * test group in test-application-wide singleton.
++   * Name of test group object (auto_ptr_group) shall
++   * be unique in tut:: namespace. Alternatively, you
++   * you may put it into anonymous namespace.
++   */
++  typedef test_group<auto_ptr_data> tf;
++  typedef tf::object object;
++  tf auto_ptr_group("std::auto_ptr");
++
++  /**
++   * Checks default constructor.
++   */
++  template<>
++  template<>
++  void object::test<1>()
++  {
++    std::auto_ptr<existing> ap;
++    ensure(ap.get()==0);
++    ensure(ap.operator->()==0);
++  }
++
++  /**
++   * Checks constructor with object
++   */
++  template<>
++  template<>
++  void object::test<2>()
++  {
++    {
++      std::auto_ptr<existing> ap(new existing(exists));
++      ensure("get",ap.get()!=0);
++      ensure_equals("constructed",exists,true);
++    }
++    // ptr left scope
++    ensure_equals("destructed",exists,false);
++  }
++
++  /**
++   * Checks operator -> and get()
++   */
++  template<>
++  template<>
++  void object::test<3>()
++  {
++    std::auto_ptr<existing> ap(new existing(exists));
++    existing* p1 = ap.get();
++    existing* p2 = ap.operator->();
++    ensure("get equiv ->",p1==p2);
++    // ensure no losing ownership
++    p1 = ap.get();
++    ensure("still owner",p1==p2);
++  }
++
++  /**
++   * Checks release()
++   */
++  template<>
++  template<>
++  void object::test<4>()
++  {
++    {
++      std::auto_ptr<existing> ap(new existing(exists));
++      existing* p1 = ap.get();
++      std::auto_ptr<existing> ap2(ap.release());
++      ensure("same pointer",p1==ap2.get());
++      ensure("lost ownership",ap.get()==0);
++    }
++    ensure("destructed",exists==false);
++  }
++
++  /**
++   * Checks assignment.
++   */
++  template<>
++  template<>
++  void object::test<5>()
++  {
++    {
++      std::auto_ptr<existing> ap(new existing(exists));
++      existing* p1 = ap.get();
++      std::auto_ptr<existing> ap2;
++      ap2 = ap;
++      ensure("same pointer",p1==ap2.get());
++      ensure("lost ownership",ap.get()==0);
++    }
++    ensure("destructed",exists==false);
++  }
++
++  /**
++   * Checks copy constructor.
++   */
++  template<>
++  template<>
++  void object::test<6>()
++  {
++    {
++      std::auto_ptr<existing> ap(new existing(exists));
++      existing* p1 = ap.get();
++      std::auto_ptr<existing> ap2(ap);
++      ensure("same pointer",p1==ap2.get());
++      ensure("lost ownership",ap.get()==0);
++    }
++    ensure("destructed",exists==false);
++  }
++}
++
++
++
++ ++
++ ++ ++ ++
++ ++
++ ++
++ ++
++ ++ ++ +diff -urNad libtut-0.0.20060329~/docs/faq.html libtut-0.0.20060329/docs/faq.html +--- libtut-0.0.20060329~/docs/faq.html 1970-01-01 01:00:00.000000000 +0100 ++++ libtut-0.0.20060329/docs/faq.html 2006-06-09 16:53:50.335608802 +0200 +@@ -0,0 +1,401 @@ ++ ++ ++ ++ ++TUT Frequently Asked Questions - TUT: C++ Unit Test Framework ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++
++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++
++ ++
++ ++
++
++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

Documentation

++ ++

Distribution

++ ++

Support

++
    ++
  • TUT Frequently Asked Questions
    often asked questions and answers for them

  • ++
  • Links
    related projects and concepts

  • ++
  • TUT Author
    who is the author

  • ++
++
++ ++
++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

TUT Frequently Asked Questions

++

What is TUT?

++

++TUT is a small and portable unit test framework for C++. It's so small that it fits into ++one header file. It's so portable that it could be used on almost any C++ platform, including ++Windows, MacOS and unices. ++

++ ++ ++

++How it's different from C++Unit (boost::test, ...)? ++

++

++C++Unit, boost::test and other frameworks perform similar tasks. ++

++ ++

++But there are some issues with most of them: ++

    ++
  • they require to build them as a library
  • ++
  • tests depend on preprocessor macros
  • ++
  • they often overloaded with features
  • ++
++

++ ++

++TUT, in contrast, is located in a single header file (20K). ++All you should do is to include it into the test module. No linking at all. ++

++ ++

++TUT uses C++ template engine to dispatch calls to test methods. Therefore ++you shouldn't even register methods as tests: template will do it for you automatically. ++As a result, the test code will be more readable. ++

++ ++

++And finally, TUT is a minimal software. It only does what it's designed for. ++It doesn't attempt to integrate with MSDN or to control production processes. It just runs tests. ++

++ ++ ++

++What compilers are supported? ++

++ ++

++Most modern compilers are supported. ++Some outdated compilers are unable to handle templates in TUT, though ++

++ ++

Supported: ++

    ++
  • GNU GCC 2.95
  • ++
  • GNU GCC 3.x (both under unix and MinGW)
  • ++
  • Borland 5.6 (Borland C++ Builder 6)
  • ++
  • Intel C++ Compiler 6.x
  • ++
  • Intel C++ Compiler 8.1
  • ++
  • Sun Studio 9: C++ 5.6 Compiler
  • ++
  • Microsoft VC7 (Microsoft VS.NET 2003 and later)
  • ++
  • Sun WorkShop 6 update 2 C++ 5.3 (probably, previous versions as well)
  • ++
++

++

Unsupported: ++

    ++
  • Borland 5.5.x (Borland C++ Builder 5)
  • ++
  • Microsoft VC6 (including SP5)
  • ++
  • Microsoft VC7 (Microsoft VS.NET 2002)
  • ++
  • C for AIX Compiler, Version 6
  • ++
  • KAI C++ Compiler
  • ++
  • Portland Group Compiler, Version 5.2-4
  • ++
++

++ ++

++ If you use TUT with any other compiler or environment please let me know. ++

++ ++

++Some broken compiler/linker/platform combinations require to make methods ensure(), ++ensure_equals and fail() to be inline, and not in anonymous namespace. Try to ++change tut.h accordingly if you see "duplicate symbol ensure" or "ensure is not found" ++during linking stage. ++

++ ++ ++

++I've taken a look at the selftest code and it looks awful ++

++ ++

++Self tests are very special beasties, and actually you've seen ++two(!) TUT frameworks running one under control of another. The case is ++quite extreme. Regular TUT tests are very simple to read; you'd better look ++at the online example. ++

++ ++ ++

++Why don't you provide methods to catch user-code exceptions? ++

++ ++

++First of all, the user-code exceptions are intercepted inside the test runner, ++and afterwards user receives them along with the test_result status. For std ++exceptions, a textual message is included into results. For the others there ++will be a message that an unknown exception was generated. ++

++ ++ ++

++I've used ensure_equals() method and compiler refused to build my code complaining that there is ambiguous overload for operator <<. ++

++

++One or both types you've provided to ensure_equals() have no operator << at all. ++Since the diagnostic message is built using std::stringstream, compiler needs the ++operator to format your objects. Either add the operator or use ensure() method ++(which doesn't tell you the exact values the objects had, just the fact they were not equal). ++

++ ++ ++

++What about segmentation faults in code being tested? What about deadlocks? ++

++ ++

++C++ Standard doesn't specify what happens if the code references ++wrong address. Thus, segmentation fault processing is system and compiler dependent, ++and shall be handled differently in each system/compiler pair. ++

++ ++

++If you want TUT to react correctly to tests failures caused by segfaults, ++you must somehow convert hardware faults into C++ exceptions. ++

++ ++

++For Win32 TUT uses SEH. You need to specify -DTUT_USE_SEH at build time. ++

++ ++

++For unixes there is no standard way to convert SIGSEGV into an exception. ++Consult your platform/compiler documentation for possible ways to do that. ++

++ ++

++You may also use restartable wrapper defined in optional header ++tut_restartable.h. It runs the tests the same way ++as regular runner does, but also logs the progress. If a test crashes the test ++application, and then test application runs again, the wrapper will load last ++log record, and continue test execution from position after the crashed test. ++

++ ++

++Of course, this requires helper script that runs test application ++until all tests will be runned. The script might be is as simple as ++

++ ++
++while true
++do
++  ./restartable && exit 0
++done
++      
++ ++

Directory examples/restartable contains simple restartable test application.

++ ++

++This approach can be extended to support deadlocks in code. The script ++must be modified to automatically kill test application after specified ++period of time. ++

++
++ ++
++ ++ ++ ++
++ ++
++ ++
++ ++
++ ++ ++ +diff -urNad libtut-0.0.20060329~/docs/howto.html libtut-0.0.20060329/docs/howto.html +--- libtut-0.0.20060329~/docs/howto.html 1970-01-01 01:00:00.000000000 +0100 ++++ libtut-0.0.20060329/docs/howto.html 2006-06-09 16:53:48.015497547 +0200 +@@ -0,0 +1,799 @@ ++ ++ ++ ++ ++TUT How-To - TUT: C++ Unit Test Framework ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++
++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++
++ ++
++ ++
++
++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

Documentation

++
    ++
  • TUT How-To
    minimum steps to make TUT work for you

  • ++
  • TUT Design
    what's hidden under the hood of tut.h, and why things are such as they ++ are

  • ++
  • TUT Usage Example
    it's better to see once...

  • ++
  • TUT As Is
    complete source of TUT

  • ++
++

Distribution

++ ++

Support

++ ++
++ ++
++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++

TUT How-To

++

About this document

++ ++

++ This text contains an explanation how you can start to use TUT in shortest possible time. ++ It also contains some introductory information on unit testing itself for those who are ++ new in the field. ++

++ ++

What is TUT

++ ++

++ TUT is a pure C++ unit test framework. ++ It's name - TUT - stands for Template Unit Tests. ++

++ ++

++ Unit test frameworks help to organize and run ++ unit tests. ++ Unit tests are used to check application correctness according to requirements. ++ Those tests are usually run often (nightly or hourly) to achieve ++ continuous integration. ++

++ ++

TUT tests organization

++ ++

++ C++ produces executable code, so tests have to be compiled into a single binary ++ called test application. The application can be built in automated mode to ++ perform nightly tests. It can also be built manually when a developer hunts for ++ bugs. ++

++ ++

++ The test application contains tests, organized into test groups. ++ The functionality of a tested application can be divided into a few separate ++ functional blocks (e.g. Access Rights, Export, Processing, ...). It is natural to ++ group tests for each block together. Each test group has a unique human-readable ++ name and normally is located in a separate file. ++

++ ++

Tests

++ ++

++ Test is a function (method) that implements some specific scenario and checks ++ if the code (unit) behaves as required. Each test usually checks only one ++ specific element of functionality. In almost any test we have a preparation ++ phase, execution phase and verification phase. For example, if we need to ++ test our container's clear() method is correct, we need: ++

    ++
  • create a container instance and fill it with some data (preparation phase)
  • ++
  • call clear() method (execution phase)
  • ++
  • ensure that size() now returns zero (verification phase)
  • ++
++

++ ++

What we are going to test?

++ ++

++ Suppose we need to create a shared_ptr class for our application. ++ We need to write tests for the class to be sure it works as it should. ++ The same tests would also guide someone who will maintain the code. ++

++ ++

++ Prior to test writing we should decide what to test. ++ Maximalist approach requires to write so many tests that altering any single ++ line of your code will break at least one test. Minimalist approach allows ++ us to write tests only for the most general or the most complex use cases. The ++ truth lies somewhere in between. We should consider common correct and ++ incorrect usage scenarios, and use them as a basis for our tests. ++

++ ++

++ For our shared_ptr we obviosly should test constructors, assignment operators, ++ referencing and passing ownership. Later we may come to some other test scenarios. ++

++ ++

Skeleton

++ ++

++ If you don't have any implemented class to test yet, it would be good to implement it ++ as a set of stub methods first. Thus you'll get an interface, and be able to write ++ your tests. Yes, this is correct: ++ you should write your tests before writing the code! ++ Writing tests often helps to understand oddities in the current interface, and fix it. ++ Besides, with the stubs all your tests will fail, so you'll be sure tests do their job. ++

++ ++

Creating Test Group

++ ++

++ Since we're writing unit tests, it would be a good idea to group the tests for our ++ class in one place to be able to run them separately. It's also natural in C++ to ++ place all the tests of a group into one compilation unit (i.e. source file). So, to ++ begin, we should create a new file. Let's call it test_shared_ptr.cpp. ++ (Final variant of the test group can be found in TUT distribution in directory examples/shared_ptr ) ++

++ ++
 
++// test_shared_ptr.cpp 
++#include <tut.h>
++namespace tut { }; 
++		
++ ++

++ As you see, you need to include TUT header file (as expected) and use namespace tut ++ for tests. You may also use anonymous namespace if your compiler allows it (you ++ will need to instantiate methods from tut namespace and some compilers refuse to ++ place such instantiations into the anonymous namespace).

++ ++

++ A test group in TUT framework is described by the special template ++ test_group<T>. The template parameter T is a type that will hold all ++ test-specific data during the test execution. Actually, the data stored in T are ++ member data of the test class. Test class is inherited from T, so any test can refer to ++ the data in T as it's member data. Complex? Not really, as you'll see. ++

++ ++

++ For simple test groups (where all data are stored in test local variables) type T ++ could be an empty struct. ++

++ ++
 
++#include <tut.h>
++namespace tut 
++{ 
++	struct shared_ptr_data { }; 
++} 
++		
++ ++

++ But when tests have complex or repeating creation phase, you may put data members ++ into T and provide constructor (and, if required, destructor) for it. For ++ each test, a new instance of T will be created. To prepare your test for execution ++ TUT will use default constructor. Similarly, after the test has been finished, ++ the destructor is called to clean up T. I.e.: ++

++ ++
 
++#include <tut.h>
++namespace tut 
++{ 
++	struct complex_data 
++	{ 
++		connection* con; 
++		complex_data()
++		{ 
++			con = db_pool.get_connection(); 
++		} 
++		~complex_data()
++		{
++			db_pool.release_connection(con); 
++		} 
++	};
++	
++	// each test from now on will have con data 
++	// member initialized by constructor
++	...
++	con->commit(); 
++	... 
++		
++ ++

++ What will happen if the constructor throws an exception? TUT will treat it as if ++ test itself failed with exception, so this test will not be executed. You'll see ++ an exception mark near the test, and if the constructor throwed something ++ printable, the message will appear. ++

++ ++

++ Exception in destructor is threated a bit different. Reaching destruction phase ++ means that the test is passed, so TUT marks test with warning status meaning that ++ test itself was OK, but something bad has happend after the test. ++

++ ++

++ Well, all we have written so far is just a type declaration. To work with a group we ++ have to have an object, so we must create the test group object. Since we need only ++ one test group object for each unit, we can (and should, actually) make this ++ object static. To prevent name clash with other test group objects in the ++ namespace tut, we should provide an unique descriptive name (or, alternatively, we may ++ put it into the anonymous namespace). The former is more correct, but the ++ descriptive name usually works well too, unless you're too terse in giving names ++ to objects. ++

++ ++
 
++#include <tut.h>
++namespace tut 
++{ 
++	struct shared_ptr_data {};
++	typedef test_group<shared_ptr_data> tg; 
++	tg shared_ptr_group("shared_ptr"); 
++}; 
++		
++ ++

++ As you see, any test group accepts a single parameter - it's human-readable name. ++ This name is used to identify the group when a programmer wants to execute all ++ tests or a single test within the group. So this name shall also be descriptive ++ enough to avoid clashes. Since we're writing tests for a specific unit, it's ++ enough to name it after the unit name. ++

++ ++

++ Test group constructor will be called at unspecified moment at the test ++ application startup. The constructor performs self-registration; it calls ++ tut::runner and asks it to store the test group object name and location. Any ++ other test group in the system undergoes the same processing, i.e. each test ++ group object registers itself. Thus, test runner can iterate all test groups or ++ execute any test group by its name. ++

++ ++

++ Newly created group has no tests associated with it. To be more precise, it has ++ predefined set of dummy tests. By default, there are 50 tests in a group, ++ including dummy ones. To create a test group with higher volume (e.g. when tests ++ are generated by a script and their number is higher) we must provide a higher ++ border of test group size when it is instantiated: ++

++ ++
 
++#include <tut.h>
++namespace tut 
++{ 
++	struct huge_test_data { };
++	// test group with maximum 500 tests 
++	typedef	test_group<huge_test_data,500> testgroup; 
++	testgroup huge_test_testgroup("huge group"); 
++}; 
++		
++ ++

++ Note also that your compiler would possibly need a command-line switch or pragma ++ to enlarge recursive instantiation depth. For g++, for example, you should ++ specify at least --ftemplate-depth-501 to increase the depth to 500. For more ++ information see your compiler documentation. ++

++ ++

Creating Tests

++ ++

Now it's time to fill our test group with content.

++ ++

++ In TUT, all tests have unique numbers inside the test group. ++ Some people believe that textual names better describe failed tests in reports. ++ I agree. But C++ templates work with numbers because they are compile-time ++ constants and refuse to do the same with strings, since strings are in fact ++ addresses of character buffers, i.e. run-time data. So I had no other choice. ++

++ ++

++ As I mentioned above, our test group already has a few dummy tests; and we can ++ replace any of them with something real just by writing our own version: ++

++ ++
 
++#include <tut.h>
++namespace tut 
++{ 
++	struct shared_ptr_data{};
++	typedef test_group<shared_ptr_data> testgroup; 
++	typedef	testgroup::object testobject; 
++	testgroup shared_ptr_testgroup("shared_ptr");
++
++	template<> template<> 
++	void testobject::test<1>() 
++	{ 
++		// do nothing test 
++	} 
++}; 
++		
++ ++

++ So far this test does nothing, but it's enough to illustrate the way we may ++ create our own test methods. Note that your shouldn't call anything like ++ REGISTER_TEST() macro or do anything similarely annoying. Just write a test, ++ and it will be executed. ++

++ ++

++ All tests in the group are methods of the type test_group<T>::object. This ++ class is directly inherited from our test data structure. In our case, it is ++

++ ++
 
++class object : public shared_ptr_data { };
++		
++ ++

++ This allows to access members of the shared_ptr_data structure directly, ++ since at the same time they are members of the object type itself. We also ++ typedef the type with testobject for brevity. ++

++ ++

++ We mark our test with number 1. Previously, test group had a dummy test with the same ++ number, but now, since we've defined our own version, it replaced the dummy test ++ as more specialized one. It's how C++ template ordering works. ++

++ ++

++ The test we've written always succeeds. Successful test returns with no ++ exceptions. Unsuccessful one either throws an exception, or fails at fail() or ++ ensure() methods (which anyway just throw the exception when failed). ++

++ ++

First real test

++ ++

++ Now we know enough to write the first real working test. This test will create ++ shared_ptr instances and check their state. We will define a small structure ++ (keepee) to use it as shared_ptr stored object type. ++

++ ++
 
++#include <tut.h> 
++#include <shared_ptr.h>
++namespace tut 
++{ 
++	struct shared_ptr_data 
++	{ 
++		struct keepee{ int data; }; 
++	};
++	
++	typedef test_group<shared_ptr_data> testgroup; 
++	typedef	testgroup::object testobject; 
++	testgroup shared_ptr_testgroup("shared_ptr");
++			
++	// checks default constructor. 
++	template<> template<> 
++	void testobject::test<1>() 
++	{ 
++		shared_ptr<keepee> def;
++		ensure("null",def.get()== 0); 
++	} 
++}; 
++		
++ ++

++ That's all! The first line creates shared_ptr. If constructor throws an ++ exception, test will fail (exceptions, including '...', are catched by the TUT ++ framework). If the first line succeeds, we must check whether the kept object is ++ null one. To do this, we use test object member function ensure(), which throws ++ std::logic_error with a given message if its second argument is not true. ++ Finally, if destructor of shared_ptr fails with exception, TUT also will report ++ this test as failed. ++

++ ++

++ It's equally easy to write a test for the scenario where we expect to get an ++ exception: let's consider our class should throw an exception if it has no stored ++ object, and the operator -> is called. ++

++ ++
 
++	// checks operator -> throws instead of returning null.
++	template<> template<> 
++	void testobject::test<2>() 
++	{ 
++		try 
++		{
++			shared_ptr<keepee> sp; 
++			sp->data = 0; 
++			fail("exception expected"); 
++		}
++		catch( const std::runtime_error& ex ) 
++		{ 
++			// ok 
++		} 
++	} 
++		
++ ++

++ Here we expect the std::runtime_error. If operator doesn't throw it, we'll force ++ the test to fail using another member function: fail(). It just throws ++ std::logic_error with a given message. If operator throws anything else, our ++ test will fail too, since we intercept only std::runtime_error, and any other ++ exception means the test has failed. ++

++ ++

++ NB: our second test has number 2 in its name; it can, actually, be any in range ++ 1..Max; the only requirement is not to write tests with the same numbers. But if you ++ did, compiler will force you to fix it anyway. ++

++ ++

++ And finally, one more test to demonstrate how to use the ensure_equals template ++ member function: ++

++ ++
 
++	/** checks keepee counting. 
++	template<> template<> 
++	void testobject::test<3>() 
++	{ 
++		shared_ptr<keepee> sp1(new keepee()); 
++		shared_ptr<keepee> sp2(sp1); 
++		ensure_equals("second copy at sp1",sp1.count(),2);
++		ensure_equals("second copy at sp2",sp2.count(),2);
++	} 
++		
++ ++

++ The test checks if the shared_ptr correctly counts references during copy ++ construction. What's interesting here is the template member ensure_equals. ++ It has an additional functionality comparing with similar call ++ ensure("second_copy",sp1.count()==2); it uses operator == to check the ++ equality of the two passed parameters and, what's more important, it uses ++ std::stringstream to format the passed parameters into a human-readable message ++ (smth like: "second copy: expected 2, got 1"). It means that ensure_equals ++ cannot be used with the types that don't have operator ++ <<; but for those having the operator it provides much more informational ++ message. ++

++ ++

++ In contrast to JUnit assertEquals, where the expected value goes before the ++ actual one, ensure_equals() accepts the expected after the actual value. I ++ believe it's more natural to read ensure_equals("msg", count, 5) as "ensure ++ that count equals to 5" rather than JUnit's "assert that 5 is the value of the ++ count". ++

++ ++

Running tests

++ ++

++ Tests are written, but an attempt to run them will be unsuccessful. We need ++ a few other bits to complete the test application. ++

++ ++

++ First of all, we need a main() method, simply because it must be in every ++ application. Second, we need a test runner singleton. Remember I said each ++ test group should register itself in singleton? So, we need that singleton. And, ++ finally, we need a kind of a callback handler to visualize our test results. ++

++ ++

++ The design of TUT doesn't strictly set a way the tests are visualized; instead, it ++ provides an opportunity to get the test results by means of callbacks. Moreover ++ it allows user to output the results in any format he prefers. Of course, there is a ++ "reference implementation" in the example/ subdirectory of the project. ++

++ ++

++ Test runner singleton is defined in tut.h, so all we need to activate it is to ++ declare an object of the type tut::test_runner_singleton in the main module ++ with a special name tut::runner. ++

++ ++

++ Now, with the test_runner we can run tests. Singleton has method get() returning a ++ reference to an instance of the test_runner class, which in turn has methods ++

    > ++
  • run_tests() to run all tests in all groups
  • ++
  • run_tests(const std::string& groupname) to run all tests in a given group
  • ++
  • run_test(const std::string& grp,int n) to run one test in the specified group.
  • ++
++

++ ++

++ So here goes our main module: ++

++ ++
 
++// main.cpp 
++#include <tut.h>
++namespace tut 
++{ 
++	test_runner_singleton runner; 
++}
++
++int main() 
++{ 
++	// run all tests in all groups 
++	runner.get().run_tests();
++	
++	// run all tests in group "shared_ptr"
++	runner.get().run_tests("shared_ptr");
++			
++	// run test number 5 in group "shared_ptr"
++	runner.get().run_test("shared_ptr",5);
++	
++	return 0; 
++} 
++		
++ ++

++ It's up to user to handle command-line arguments or GUI messages and map those ++ arguments/messages to actual calls to test runner. Again, as you see, TUT ++ doesn't restrict user here. ++

++ ++

++ But, the last question is still unanswered: how do we get our test results? The ++ answer lies inside tut::callback interface. We could create it's subclass, ++ and write a few simple methods. We also can omit any method since they have ++ default no-op implementation. Each corresponding method is called in the ++ following cases: ++

    ++
  • a new test run has started;
  • ++
  • test is finished;
  • ++
  • test run is finished.
  • ++
++

++ ++

++ Here is a minimal implementation: ++

++ ++
 
++class visualizator : public tut::callback 
++{ 
++public: 
++	void run_started(){ }
++	void test_completed(const tut::test_result& tr) 
++	{ // ... show test result here ... }
++	void run_completed(){ } 
++}; 
++		
++ ++

++ The most important is the test_completed() method; its parameter has type ++ test_result, and contains everything about the finished test, from its group ++ name and number to the exception message, if any. Member variable result is an ++ enum which contains status of the test: ok, fail or ex. Take a look at the ++ examples/basic/main.cpp for more complete visualizator. ++

++ ++

++ Visualizator should be passed to the test_runner before the run. Knowing that, we are ++ ready to write the final version of our main module: ++

++ ++
 
++#include <tut.h>
++namespace tut 
++{ 
++	test_runner_singleton runner; 
++}
++
++class callback : public tut::callback 
++{ 
++public: 
++	void run_started(){ std::cout << "\nbegin"; }
++	void test_completed(const tut::test_result& tr) 
++	{ std::cout << tr.test_pos << "=" << tr.result << std::flush; }
++	void run_completed(){ std::cout << "\nend"; } 
++};
++
++int main() 
++{ 
++	callback clbk; 
++	runner.get().set_callback(&clbk);
++	runner.get().run_tests(); 
++	return 0; 
++} 
++		
++ ++

++ That's it. We are now ready to link and run our test application. Do it as often as ++ possible; once a day is a definite must. I hope TUT will help you to make your ++ application more robust and relieve your testing pain. Feel free to send your ++ questions, suggestions and critical opinions to me; I'll do my best to address ++ them asap. ++

++
++ ++
++ ++ ++ ++
++ ++
++ ++
++ ++
++ ++ ++ --- libtut-0.0.20070706.orig/debian/patches/10-fix-example-paths.dpatch +++ libtut-0.0.20070706/debian/patches/10-fix-example-paths.dpatch @@ -0,0 +1,126 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 10-fix-example-paths.dpatch by +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: No description. + +@DPATCH@ +diff -urNad libtut-0.0.20070706~/Makefile.gcc-unix libtut-0.0.20070706/Makefile.gcc-unix +--- libtut-0.0.20070706~/Makefile.gcc-unix 2008-02-05 12:23:44.000000000 +0100 ++++ libtut-0.0.20070706/Makefile.gcc-unix 2008-02-05 12:23:52.000000000 +0100 +@@ -1,5 +1,5 @@ + CXX=g++ +-CXXOPTS=-ftemplate-depth-100 -I$(TUT) -Wall -O2 -c -o ++CXXOPTS=-ftemplate-depth-100 -Wall -O2 -c -o + LNK=g++ + LNKOPTS=-o + SFX=_gcc_unix +diff -urNad libtut-0.0.20070706~/examples/basic/Makefile.common libtut-0.0.20070706/examples/basic/Makefile.common +--- libtut-0.0.20070706~/examples/basic/Makefile.common 2008-02-05 12:23:44.000000000 +0100 ++++ libtut-0.0.20070706/examples/basic/Makefile.common 2008-02-05 12:23:52.000000000 +0100 +@@ -1,8 +1,6 @@ + TGT=example$(SFX) + OBJS=main$(OFX) test_vector$(OFX) test_set$(OFX) test_auto_ptr$(OFX) + +-HEADERS=../../tut/tut.hpp +- + all: $(TGT) + + clean: +@@ -11,14 +9,14 @@ + $(TGT): $(OBJS) + $(LNK) $(LNKOPTS)$(TGT) $(OBJS) + +-test_vector$(OFX) : test_vector.cpp $(HEADERS) ++test_vector$(OFX) : test_vector.cpp + $(CXX) $(CXXOPTS)test_vector$(OFX) test_vector.cpp + +-test_set$(OFX) : test_set.cpp $(HEADERS) ++test_set$(OFX) : test_set.cpp + $(CXX) $(CXXOPTS)test_set$(OFX) test_set.cpp + +-test_auto_ptr$(OFX) : test_auto_ptr.cpp $(HEADERS) ++test_auto_ptr$(OFX) : test_auto_ptr.cpp + $(CXX) $(CXXOPTS)test_auto_ptr$(OFX) test_auto_ptr.cpp + +-main$(OFX) : main.cpp $(HEADERS) ++main$(OFX) : main.cpp + $(CXX) $(CXXOPTS)main$(OFX) main.cpp +diff -urNad libtut-0.0.20070706~/examples/basic/Makefile.gcc-unix libtut-0.0.20070706/examples/basic/Makefile.gcc-unix +--- libtut-0.0.20070706~/examples/basic/Makefile.gcc-unix 2008-02-05 12:23:44.000000000 +0100 ++++ libtut-0.0.20070706/examples/basic/Makefile.gcc-unix 2008-02-05 12:23:52.000000000 +0100 +@@ -1,3 +1,3 @@ +-TUT=../.. +-include ../../Makefile.gcc-unix ++TUT=/usr/include ++include ../Makefile.gcc-unix + include Makefile.common +diff -urNad libtut-0.0.20070706~/examples/restartable/Makefile.common libtut-0.0.20070706/examples/restartable/Makefile.common +--- libtut-0.0.20070706~/examples/restartable/Makefile.common 2008-02-05 12:23:44.000000000 +0100 ++++ libtut-0.0.20070706/examples/restartable/Makefile.common 2008-02-05 12:23:52.000000000 +0100 +@@ -1,8 +1,6 @@ + TGT=example$(SFX) + OBJS=main$(OFX) test_segfaults$(OFX) test_segfaults2$(OFX) + +-HEADERS=../../tut/tut.hpp ../../tut/tut_restartable.hpp +- + all: $(TGT) + + clean: +@@ -11,11 +9,11 @@ + $(TGT): $(OBJS) + $(LNK) $(LNKOPTS)$(TGT) $(OBJS) + +-test_segfaults$(OFX) : test_segfaults.cpp $(HEADERS) ++test_segfaults$(OFX) : test_segfaults.cpp + $(CXX) $(CXXOPTS)test_segfaults$(OFX) test_segfaults.cpp + +-test_segfaults2$(OFX) : test_segfaults2.cpp $(HEADERS) ++test_segfaults2$(OFX) : test_segfaults2.cpp + $(CXX) $(CXXOPTS)test_segfaults2$(OFX) test_segfaults2.cpp + +-main$(OFX) : main.cpp $(HEADERS) ++main$(OFX) : main.cpp + $(CXX) $(CXXOPTS)main$(OFX) main.cpp +diff -urNad libtut-0.0.20070706~/examples/restartable/Makefile.gcc-unix libtut-0.0.20070706/examples/restartable/Makefile.gcc-unix +--- libtut-0.0.20070706~/examples/restartable/Makefile.gcc-unix 2008-02-05 12:23:44.000000000 +0100 ++++ libtut-0.0.20070706/examples/restartable/Makefile.gcc-unix 2008-02-05 12:23:52.000000000 +0100 +@@ -1,3 +1,3 @@ +-TUT=../.. +-include ../../Makefile.gcc-unix ++TUT=/usr/include ++include ../Makefile.gcc-unix + include Makefile.common +diff -urNad libtut-0.0.20070706~/examples/shared_ptr/Makefile.common libtut-0.0.20070706/examples/shared_ptr/Makefile.common +--- libtut-0.0.20070706~/examples/shared_ptr/Makefile.common 2007-07-06 20:58:04.000000000 +0200 ++++ libtut-0.0.20070706/examples/shared_ptr/Makefile.common 2008-02-05 12:26:50.000000000 +0100 +@@ -1,8 +1,6 @@ + TGT=shared_ptr$(SFX) + OBJS=main$(OFX) test_shared_ptr$(OFX) + +-HEADERS=../../tut/tut.hpp +- + all: $(TGT) + + clean: +@@ -11,9 +9,9 @@ + $(TGT): $(OBJS) + $(LNK) $(LNKOPTS)$(TGT) $(OBJS) + +-test_shared_ptr$(OFX) : test_shared_ptr.cpp $(HEADERS) ++test_shared_ptr$(OFX) : test_shared_ptr.cpp + $(CXX) $(CXXOPTS)test_shared_ptr$(OFX) test_shared_ptr.cpp + +-main$(OFX) : main.cpp $(HEADERS) ++main$(OFX) : main.cpp + $(CXX) $(CXXOPTS)main$(OFX) main.cpp + +diff -urNad libtut-0.0.20070706~/examples/shared_ptr/Makefile.gcc-unix libtut-0.0.20070706/examples/shared_ptr/Makefile.gcc-unix +--- libtut-0.0.20070706~/examples/shared_ptr/Makefile.gcc-unix 2005-06-22 06:40:03.000000000 +0200 ++++ libtut-0.0.20070706/examples/shared_ptr/Makefile.gcc-unix 2008-02-05 12:27:18.000000000 +0100 +@@ -1,3 +1,3 @@ +-TUT=../.. +-include ../../Makefile.gcc-unix ++TUT=/usr/include ++include ../Makefile.gcc-unix + include Makefile.common --- libtut-0.0.20070706.orig/debian/patches/Makefile +++ libtut-0.0.20070706/debian/patches/Makefile @@ -0,0 +1,3 @@ +00list: $(wildcard *.dpatch) + ls -1 $^ | sed -ne 's,\.dpatch$$,,p' | sort -n >| 00list +.PHONY: 00list --- libtut-0.0.20070706.orig/debian/patches/00list +++ libtut-0.0.20070706/debian/patches/00list @@ -0,0 +1,2 @@ +10-fix-example-paths +90-docs --- libtut-0.0.20070706.orig/debian/README.Debian +++ libtut-0.0.20070706/debian/README.Debian @@ -0,0 +1,7 @@ +libtut for Debian GNU/Linux +=========================== + +Do not wonder about the absence of a 'libtut0' package; there is none. The TUT +framework is a header-only library. + + -- martin f. krafft Wed, 11 May 2005 21:44:11 +0200 --- libtut-0.0.20070706.orig/debian/rules +++ libtut-0.0.20070706/debian/rules @@ -0,0 +1,81 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +include /usr/share/dpatch/dpatch.make + +configure: configure-stamp +configure-stamp: patch + make -sC debian/patches + touch $@ + +build: build-stamp +build-stamp: configure + dh_testdir + touch build-stamp + +harikiri: unpatch +.PHONY: harikiri + +clean: clean-patched harikiri +clean-patched: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + dh_install + +binary-indep: build install + dh_testdir -i + dh_testroot -i + dh_installchangelogs -i + dh_installdocs -i + + dh_installexamples -i + for ext in bcc icl mingw2 mingw3 vc7; do \ + rm -f debian/libtut-dev/usr/share/doc/libtut-dev/examples/*/Makefile.$$ext; \ + done + + for mf in debian/libtut-dev/usr/share/doc/libtut-dev/examples/*/Makefile.gcc-unix; do \ + ln -s Makefile.gcc-unix $${mf%.gcc-unix}; \ + done + + dh_link -i + dh_compress -i -X.cpp + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +binary-arch: build install + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install --- libtut-0.0.20070706.orig/debian/README.gcc-3.4-and-up +++ libtut-0.0.20070706/debian/README.gcc-3.4-and-up @@ -0,0 +1,37 @@ +libtut README for gcc 3.4 (and beyond) +====================================== + +gcc 3.4 has tighter checks on many aspects of C++. Thus, if you compile your +tests with g++-3.4, you may run into some problems. In particular: + + - You cannot put your tests into a unnamed namespace anymore. g++ will + complain that + + error: specialization of + `template template void tut::test_object::test()' + in different namespace from definition of + `template template void tut::test_object::test()' + + the solution is to put all tests into the tut namespace. + + - Without unnamed namespaces, the one-definition rule will bite if you use + multiple test files and you have lines like + + typedef tut::test_group TestGroupType; + typedef TestGroupType::object TestObjectType; + TestGroupType test_group_registration("Neuron"); + + in your files. The problem is that test_group_registration will be defined + multiple times, which the linker will complain about: + + test_Assertion.o(.bss+0x0):/usr/include/c++/3.4/bits/locale_facets.tcc:2444: + multiple definition of `tut::test_group_registration' + + Here, the solution is to frame the last of the three lines in an unnamed + namespace: + + typedef tut::test_group TestGroupType; + typedef TestGroupType::object TestObjectType; + namespace { TestGroupType test_group_registration("Neuron"); } + + -- martin f. krafft Wed, 11 May 2005 21:44:11 +0200 --- libtut-0.0.20070706.orig/debian/compat +++ libtut-0.0.20070706/debian/compat @@ -0,0 +1 @@ +5