Blame doc/Money.dox

Packit Service e31359
/*! \page money_example Money, a step by step example
Packit Service e31359
Packit Service e31359
\section Table of contents
Packit Service e31359
Packit Service e31359
  - \ref sec_setting_vc
Packit Service e31359
  - \ref sec_setting_unix
Packit Service e31359
  - \ref sec_running_test
Packit Service e31359
  - \ref sec_adding_testfixture
Packit Service e31359
  - \ref sec_first_tests
Packit Service e31359
  - \ref sec_more_tests
Packit Service e31359
  - \ref sec_credits
Packit Service e31359
Packit Service e31359
  The example explored in this article can be found in \c examples/Money/.
Packit Service e31359
Packit Service e31359
Packit Service e31359
Packit Service e31359
\section sec_setting_vc Setting up your project (VC++)
Packit Service e31359
Packit Service e31359
\subsection sec_install Compiling and installing CppUnit libaries
Packit Service e31359
Packit Service e31359
In the following document, $CPPUNIT is the directory where you unpacked %CppUnit:
Packit Service e31359
$CPPUNIT/:
Packit Service e31359
	include/
Packit Service e31359
	lib/
Packit Service e31359
	src/
Packit Service e31359
		cppunit/
Packit Service e31359
Packit Service e31359
First, you need to compile %CppUnit libraries:
Packit Service e31359
- Open the $CPPUNIT/src/CppUnitLibraries.dsw workspace in VC++.
Packit Service e31359
- In the 'Build' menu, select 'Batch Build...'
Packit Service e31359
- In the batch build dialog, select all projects and press the build button.
Packit Service e31359
- The resulting libraries can be found in the $CPPUNIT/lib/ directory.
Packit Service e31359
Packit Service e31359
Once it is done, you need to tell VC++ where are the includes and libraries
Packit Service e31359
to use them in other projects. Open the 'Tools/Options...' dialog, and in the
Packit Service e31359
'Directories' tab, select 'include files' in the combo. Add a new entry that
Packit Service e31359
points to $CPPUNIT/include/. Change to 'libraries files' in the combo and 
Packit Service e31359
add a new entry for $CPPUNIT/lib/. Repeat the process with 'source files' 
Packit Service e31359
and add $CPPUNIT/src/cppunit/.
Packit Service e31359
Packit Service e31359
\subsection sec_getting_started Getting started
Packit Service e31359
Packit Service e31359
Creates a new console application ('a simple application' template will do).
Packit Service e31359
Let's link %CppUnit library to our project. In the project settings:
Packit Service e31359
- In tab 'C++', combo 'Code generation', set the combo to 'Multithreaded DLL'
Packit Service e31359
for the release configuration, and 'Debug Multithreaded DLL' for the debug
Packit Service e31359
configure,
Packit Service e31359
- In tab 'C++', combo 'C++ langage', for All Configurations, check 
Packit Service e31359
'enable Run-Time Type Information (RTTI)',
Packit Service e31359
- In tab 'Link', in the 'Object/library modules' field, add cppunitd.lib for
Packit Service e31359
the debug configuration, and cppunit.lib for the release configuration.
Packit Service e31359
Packit Service e31359
We're done !
Packit Service e31359
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
    
Packit Service e31359
      
Packit Service e31359
        
Packit Service e31359
          
Packit Service e31359
\section sec_setting_unix Setting up your project (Unix)
Packit Service e31359
We'll use \c autoconf and \c automake to make it simple to 
Packit Service e31359
create our build environment. Create a directory somewhere to 
Packit Service e31359
hold the code we're going to build. Create \c configure.in and 
Packit Service e31359
\c Makefile.am in that directory to get started.
Packit Service e31359
Packit Service e31359
<tt>configure.in</tt>
Packit Service e31359
\verbatim
Packit Service e31359
dnl Process this file with autoconf to produce a configure script.
Packit Service e31359
AC_INIT(Makefile.am)
Packit Service e31359
AM_INIT_AUTOMAKE(money,0.1)
Packit Service e31359
AM_PATH_CPPUNIT(1.9.6)
Packit Service e31359
AC_PROG_CXX
Packit Service e31359
AC_PROG_CC
Packit Service e31359
AC_PROG_INSTALL
Packit Service e31359
AC_OUTPUT(Makefile)\endverbatim
Packit Service e31359
Packit Service e31359
<tt>Makefile.am</tt>
Packit Service e31359
\verbatim
Packit Service e31359
# Rules for the test code (use `make check` to execute)
Packit Service e31359
TESTS = MoneyApp
Packit Service e31359
check_PROGRAMS = $(TESTS)
Packit Service e31359
MoneyApp_SOURCES = Money.h MoneyTest.h MoneyTest.cpp MoneyApp.cpp
Packit Service e31359
MoneyApp_CXXFLAGS = $(CPPUNIT_CFLAGS)
Packit Service e31359
MoneyApp_LDFLAGS = $(CPPUNIT_LIBS) -ldl\endverbatim
Packit Service e31359
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
    
Packit Service e31359
      
Packit Service e31359
        
Packit Service e31359
          
Packit Service e31359
            
Packit Service e31359
\section sec_running_test Running our tests
Packit Service e31359
Packit Service e31359
We have a main that doesn't do anything. Let's start by adding the mechanics
Packit Service e31359
to run our tests (remember, test before you code ;-) ). For this example, 
Packit Service e31359
we will use a TextTestRunner with the CompilerOutputter for post-build 
Packit Service e31359
testing:
Packit Service e31359
Packit Service e31359
<tt>MoneyApp.cpp</tt>
Packit Service e31359
\code
Packit Service e31359
#include "stdafx.h"
Packit Service e31359
#include <cppunit/CompilerOutputter.h>
Packit Service e31359
#include <cppunit/extensions/TestFactoryRegistry.h>
Packit Service e31359
#include <cppunit/ui/text/TestRunner.h>
Packit Service e31359
Packit Service e31359
Packit Service e31359
int main(int argc, char* argv[])
Packit Service e31359
{
Packit Service e31359
  // Get the top level suite from the registry
Packit Service e31359
  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
Packit Service e31359
Packit Service e31359
  // Adds the test to the list of test to run
Packit Service e31359
  CppUnit::TextUi::TestRunner runner;
Packit Service e31359
  runner.addTest( suite );
Packit Service e31359
Packit Service e31359
  // Change the default outputter to a compiler error format outputter
Packit Service e31359
  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
Packit Service e31359
                                                       std::cerr ) );
Packit Service e31359
  // Run the tests.
Packit Service e31359
  bool wasSucessful = runner.run();
Packit Service e31359
Packit Service e31359
  // Return error code 1 if the one of test failed.
Packit Service e31359
  return wasSucessful ? 0 : 1;
Packit Service e31359
}\endcode
Packit Service e31359
Packit Service e31359
  VC++: Compile and run (Ctrl+F5).
Packit Service e31359
Packit Service e31359
  Unix: First build. Since we don't have all the file yet, let's create them
Packit Service e31359
  and build our application for the first time:
Packit Service e31359
\verbatim
Packit Service e31359
touch Money.h MoneyTest.h MoneyTest.cpp
Packit Service e31359
aclocal -I /usr/local/share/aclocal
Packit Service e31359
autoconf
Packit Service e31359
automake -a
Packit Service e31359
touch NEWS README AUTHORS ChangeLog # To make automake happy
Packit Service e31359
./configure
Packit Service e31359
make check\endverbatim
Packit Service e31359
Packit Service e31359
  Our application will report that everything
Packit Service e31359
is fine and no test were run. So let's add some tests...
Packit Service e31359
Packit Service e31359
Packit Service e31359
Packit Service e31359
\subsection sec_post_build Setting up automated post-build testing (VC++)
Packit Service e31359
Packit Service e31359
What does post-build testing means? It means that each time you compile,
Packit Service e31359
the test are automatically run when the build finish. This is very
Packit Service e31359
useful, if you compile often you can know that you just 'broke' something,
Packit Service e31359
or that everything is still working fine.
Packit Service e31359
Packit Service e31359
Let's adds that to our project, In the project settings, in the 
Packit Service e31359
'post-build step' tab:
Packit Service e31359
- Select 'All configurations' (upper left combo)
Packit Service e31359
- In the 'Post-build description', enter 'Unit testing...'
Packit Service e31359
- In 'post-build command(s)', add a new line: <tt>\$(TargetPath)</tt>
Packit Service e31359
Packit Service e31359
<tt>\$(TargetPath)</tt> expands into the name of your application:
Packit Service e31359
Debug\\MoneyApp.exe in debug configuration and Release\\MoneyApp.exe in release
Packit Service e31359
configuration.
Packit Service e31359
Packit Service e31359
What we are doing is say to VC++ to run our application for each build. 
Packit Service e31359
Notices the last line of \c main(), it returns a different error code, 
Packit Service e31359
depending on weither or not a test failed. If the code returned by
Packit Service e31359
an application is not 0 in post-build step, it tell VC++ that the build
Packit Service e31359
step failed.
Packit Service e31359
Packit Service e31359
Compile. Notice that the application's output is now in the build window.
Packit Service e31359
How convenient!
Packit Service e31359
Packit Service e31359
  (Unix: tips to integrate make check into various IDE?)
Packit Service e31359
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
    
Packit Service e31359
      
Packit Service e31359
        
Packit Service e31359
          
Packit Service e31359
\section sec_adding_testfixture Adding the TestFixture
Packit Service e31359
Packit Service e31359
For this example, we are going to write a simple money class. Money
Packit Service e31359
has an amount and a currency. Let's begin by creating a fixture where
Packit Service e31359
we can put our tests, and add single test to test Money constructor:
Packit Service e31359
Packit Service e31359
<tt>MoneyTest.h:</tt>
Packit Service e31359
\code
Packit Service e31359
#ifndef MONEYTEST_H
Packit Service e31359
#define MONEYTEST_H
Packit Service e31359
Packit Service e31359
#include <cppunit/extensions/HelperMacros.h>
Packit Service e31359
Packit Service e31359
class MoneyTest : public CppUnit::TestFixture
Packit Service e31359
{
Packit Service e31359
  CPPUNIT_TEST_SUITE( MoneyTest );
Packit Service e31359
  CPPUNIT_TEST( testConstructor );
Packit Service e31359
  CPPUNIT_TEST_SUITE_END();
Packit Service e31359
Packit Service e31359
public:
Packit Service e31359
  void setUp();
Packit Service e31359
  void tearDown();
Packit Service e31359
Packit Service e31359
  void testConstructor();
Packit Service e31359
};
Packit Service e31359
Packit Service e31359
#endif  // MONEYTEST_H\endcode
Packit Service e31359
Packit Service e31359
- CPPUNIT_TEST_SUITE declares that our Fixture's test suite.
Packit Service e31359
- CPPUNIT_TEST adds a test to our test suite. The test is implemented 
Packit Service e31359
by a method named testConstructor().
Packit Service e31359
- setUp() and tearDown() are use to setUp/tearDown some fixtures. We are
Packit Service e31359
not using any for now.
Packit Service e31359
Packit Service e31359
<tt>MoneyTest.cpp</tt>
Packit Service e31359
\code
Packit Service e31359
#include "stdafx.h"
Packit Service e31359
#include "MoneyTest.h"
Packit Service e31359
Packit Service e31359
// Registers the fixture into the 'registry'
Packit Service e31359
CPPUNIT_TEST_SUITE_REGISTRATION( MoneyTest );
Packit Service e31359
Packit Service e31359
Packit Service e31359
void 
Packit Service e31359
MoneyTest::setUp()
Packit Service e31359
{
Packit Service e31359
}
Packit Service e31359
Packit Service e31359
Packit Service e31359
void 
Packit Service e31359
MoneyTest::tearDown()
Packit Service e31359
{
Packit Service e31359
}
Packit Service e31359
Packit Service e31359
Packit Service e31359
void 
Packit Service e31359
MoneyTest::testConstructor()
Packit Service e31359
{
Packit Service e31359
  CPPUNIT_FAIL( "not implemented" );
Packit Service e31359
}
Packit Service e31359
\endcode
Packit Service e31359
Packit Service e31359
Compile. As expected, it reports that a test failed. Press the \c F4 key
Packit Service e31359
(Go to next Error). VC++ jump right to our failed assertion CPPUNIT_FAIL.
Packit Service e31359
We can not ask better in term of integration!
Packit Service e31359
\verbatim
Packit Service e31359
Compiling...
Packit Service e31359
MoneyTest.cpp
Packit Service e31359
Linking...
Packit Service e31359
Unit testing...
Packit Service e31359
.F
Packit Service e31359
G:\prg\vc\Lib\cppunit\examples\money\MoneyTest.cpp(26):Assertion
Packit Service e31359
Test name: MoneyTest.testConstructor
Packit Service e31359
not implemented
Packit Service e31359
Failures !!!
Packit Service e31359
Run: 1   Failure total: 1   Failures: 1   Errors: 0
Packit Service e31359
Error executing d:\winnt\system32\cmd.exe.
Packit Service e31359
Packit Service e31359
moneyappd.exe - 1 error(s), 0 warning(s)
Packit Service e31359
\endverbatim
Packit Service e31359
Packit Service e31359
Well, we have everything set up, let's start doing some real testing.
Packit Service e31359
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
    
Packit Service e31359
      
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
\section sec_first_tests Our first tests
Packit Service e31359
Packit Service e31359
Let's write our first real test. A test is usually decomposed in three parts:
Packit Service e31359
- setting up datas used by the test
Packit Service e31359
- doing some processing based on those datas
Packit Service e31359
- checking the result of the processing
Packit Service e31359
Packit Service e31359
\code
Packit Service e31359
void 
Packit Service e31359
MoneyTest::testConstructor()
Packit Service e31359
{
Packit Service e31359
  // Set up
Packit Service e31359
  const std::string currencyFF( "FF" );
Packit Service e31359
  const double longNumber = 12345678.90123;
Packit Service e31359
Packit Service e31359
  // Process
Packit Service e31359
  Money money( longNumber, currencyFF );
Packit Service e31359
Packit Service e31359
  // Check
Packit Service e31359
  CPPUNIT_ASSERT_EQUAL( longNumber, money.getAmount() );
Packit Service e31359
  CPPUNIT_ASSERT_EQUAL( currencyFF, money.getCurrency() );
Packit Service e31359
}\endcode
Packit Service e31359
Packit Service e31359
Well, we finally have a good start of what our Money class will
Packit Service e31359
look like. Let's start implementing...
Packit Service e31359
Packit Service e31359
<tt>Money.h</tt>
Packit Service e31359
\code
Packit Service e31359
#ifndef MONEY_H
Packit Service e31359
#define MONEY_H
Packit Service e31359
Packit Service e31359
#include <string>
Packit Service e31359
Packit Service e31359
class Money
Packit Service e31359
{
Packit Service e31359
public:
Packit Service e31359
  Money( double amount, std::string currency )
Packit Service e31359
    : m_amount( amount )
Packit Service e31359
    , m_currency( currency )
Packit Service e31359
  {
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
  double getAmount() const
Packit Service e31359
  {
Packit Service e31359
    return m_amount;
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
  std::string getCurrency() const
Packit Service e31359
  {
Packit Service e31359
    return m_currency;
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
private:
Packit Service e31359
  double m_amount;
Packit Service e31359
  std::string m_currency;
Packit Service e31359
};
Packit Service e31359
Packit Service e31359
#endif\endcode
Packit Service e31359
Packit Service e31359
Include <tt>Money.h</tt> in MoneyTest.cpp and compile.
Packit Service e31359
Packit Service e31359
Hum, an assertion failed! Press F4, and we jump to the assertion
Packit Service e31359
that checks the currency of the constructed money object. The report
Packit Service e31359
indicates that string is not equal to expected value. There is only
Packit Service e31359
two ways for this to happen: the member was badly initialized or we
Packit Service e31359
returned the wrong value. After a quick check, we find out it is the former.
Packit Service e31359
Let's fix that:
Packit Service e31359
Packit Service e31359
<tt>Money.h</tt>
Packit Service e31359
\code
Packit Service e31359
  Money( double amount, std::string currency )
Packit Service e31359
    : m_amount( amount )
Packit Service e31359
    , m_currency( currency )
Packit Service e31359
  {
Packit Service e31359
  }\endcode
Packit Service e31359
Packit Service e31359
Compile. Our test finally pass!
Packit Service e31359
Let's add some functionnality to our Money class.
Packit Service e31359
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
    
Packit Service e31359
      
Packit Service e31359
        
Packit Service e31359
          
Packit Service e31359
            
Packit Service e31359
\section sec_more_tests Adding more tests
Packit Service e31359
Packit Service e31359
\subsection sec_equal Testing for equality
Packit Service e31359
Packit Service e31359
  We want to check if to Money object are equal. Let's start by adding
Packit Service e31359
a new test to the suite, then add our method:
Packit Service e31359
Packit Service e31359
<tt>MoneyTest.h</tt>
Packit Service e31359
\code
Packit Service e31359
  CPPUNIT_TEST_SUITE( MoneyTest );
Packit Service e31359
  CPPUNIT_TEST( testConstructor );
Packit Service e31359
  CPPUNIT_TEST( testEqual );
Packit Service e31359
  CPPUNIT_TEST_SUITE_END();
Packit Service e31359
public:
Packit Service e31359
  ...
Packit Service e31359
  void testEqual();
Packit Service e31359
\endcode
Packit Service e31359
Packit Service e31359
<tt>MoneyTest.cpp</tt>
Packit Service e31359
\code
Packit Service e31359
void
Packit Service e31359
MoneyTest::testEqual()
Packit Service e31359
{
Packit Service e31359
  // Set up
Packit Service e31359
  const Money money123FF( 123, "FF" );
Packit Service e31359
  const Money money123USD( 123, "USD" );
Packit Service e31359
  const Money money12FF( 12, "FF" );
Packit Service e31359
  const Money money12USD( 12, "USD" );
Packit Service e31359
Packit Service e31359
  // Process & Check
Packit Service e31359
  CPPUNIT_ASSERT( money123FF == money123FF );     // ==
Packit Service e31359
  CPPUNIT_ASSERT( money12FF != money123FF );      // != amount
Packit Service e31359
  CPPUNIT_ASSERT( money123USD != money123FF );    // != currency
Packit Service e31359
  CPPUNIT_ASSERT( money12USD != money123FF );     // != currency and != amount
Packit Service e31359
}\endcode
Packit Service e31359
Packit Service e31359
  Let's implements \c operator \c == and \c operator \c != in Money.h:
Packit Service e31359
Packit Service e31359
<tt>Money.h</tt>
Packit Service e31359
\code
Packit Service e31359
class Money
Packit Service e31359
{
Packit Service e31359
public:
Packit Service e31359
...
Packit Service e31359
  bool operator ==( const Money &other ) const
Packit Service e31359
  {
Packit Service e31359
    return m_amount == other.m_amount  &&  
Packit Service e31359
           m_currency == other.m_currency;
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
  bool operator !=( const Money &other ) const
Packit Service e31359
  {
Packit Service e31359
    return (*this == other);
Packit Service e31359
  }
Packit Service e31359
};
Packit Service e31359
\endcode
Packit Service e31359
Packit Service e31359
  Compile, run... Ooops... Press F4, it seems we're having trouble 
Packit Service e31359
with \c operator \c !=. Let's fix that:
Packit Service e31359
\code
Packit Service e31359
  bool operator !=( const Money &other ) const
Packit Service e31359
  {
Packit Service e31359
    return !(*this == other);
Packit Service e31359
  }\endcode
Packit Service e31359
Packit Service e31359
Compile, run. Finally got it working!
Packit Service e31359
Packit Service e31359
Packit Service e31359
Packit Service e31359
\subsection sec_opadd Adding moneys
Packit Service e31359
Packit Service e31359
  Let's add our test 'testAdd' to MoneyTest. You know the routine...
Packit Service e31359
Packit Service e31359
<tt>MoneyTest.cpp</tt>
Packit Service e31359
\code
Packit Service e31359
void 
Packit Service e31359
MoneyTest::testAdd()
Packit Service e31359
{
Packit Service e31359
  // Set up
Packit Service e31359
  const Money money12FF( 12, "FF" );
Packit Service e31359
  const Money expectedMoney( 135, "FF" );
Packit Service e31359
Packit Service e31359
  // Process
Packit Service e31359
  Money money( 123, "FF" );
Packit Service e31359
  money += money12FF;
Packit Service e31359
Packit Service e31359
  // Check
Packit Service e31359
  CPPUNIT_ASSERT( expectedMoney == money );           // add works
Packit Service e31359
  CPPUNIT_ASSERT( &money == &(money += money12FF) );  // add returns ref. on 'this'.
Packit Service e31359
}\endcode
Packit Service e31359
Packit Service e31359
  While writing that test case, you ask yourself, what is the result of
Packit Service e31359
adding money of currencies. Obviously this is an error and it should be
Packit Service e31359
reported, say let throw an exception, say \c IncompatibleMoneyError, 
Packit Service e31359
when the currencies are not equal. We will write another test case
Packit Service e31359
for this later. For now let get our testAdd() case working:
Packit Service e31359
Packit Service e31359
<tt>Money.h</tt>
Packit Service e31359
\code
Packit Service e31359
class Money
Packit Service e31359
{
Packit Service e31359
public:
Packit Service e31359
...
Packit Service e31359
  Money &operator +=( const Money &other )
Packit Service e31359
  {
Packit Service e31359
    m_amount += other.m_amount;
Packit Service e31359
    return *this;
Packit Service e31359
  }
Packit Service e31359
}; \endcode
Packit Service e31359
Packit Service e31359
Compile, run. Miracle, everything is fine! Just to be sure the test is indeed
Packit Service e31359
working, in the above code, change \c m_amount \c += to \c -=. Build and 
Packit Service e31359
check that it fails (always be suspicious of test that work the first 
Packit Service e31359
time: you may have forgotten to add it to the suite for example)! 
Packit Service e31359
Change the code back so that all the tests are working.
Packit Service e31359
  
Packit Service e31359
  Let's the incompatible money test case before we forget about it...
Packit Service e31359
That test case expect an \c IncompatibleMoneyError exception to be thrown. 
Packit Service e31359
%CppUnit can test that for us, you need to specify that the test case
Packit Service e31359
expect an exception when you add it to the suite:
Packit Service e31359
  
Packit Service e31359
<tt>MoneyTest.h</tt>
Packit Service e31359
\code
Packit Service e31359
class MoneyTest : public CppUnit::TestFixture
Packit Service e31359
{
Packit Service e31359
  CPPUNIT_TEST_SUITE( MoneyTest );
Packit Service e31359
  CPPUNIT_TEST( testConstructor );
Packit Service e31359
  CPPUNIT_TEST( testEqual );
Packit Service e31359
  CPPUNIT_TEST( testAdd );
Packit Service e31359
  CPPUNIT_TEST_EXCEPTION( testAddThrow, IncompatibleMoneyError );
Packit Service e31359
  CPPUNIT_TEST_SUITE_END();
Packit Service e31359
public:
Packit Service e31359
  ...
Packit Service e31359
  void testAddThrow();
Packit Service e31359
};\endcode
Packit Service e31359
Packit Service e31359
By convention, you end the name of such tests with \c 'Throw', that way, you
Packit Service e31359
know that the test expect an exception to be thrown. Let's write our test case:
Packit Service e31359
Packit Service e31359
<tt>MoneyTest.cpp</tt>
Packit Service e31359
\code
Packit Service e31359
void 
Packit Service e31359
MoneyTest::testAddThrow()
Packit Service e31359
{
Packit Service e31359
  // Set up
Packit Service e31359
  const Money money123FF( 123, "FF" );
Packit Service e31359
Packit Service e31359
  // Process
Packit Service e31359
  Money money( 123, "USD" );
Packit Service e31359
  money += money123FF;        // should throw an exception
Packit Service e31359
}
Packit Service e31359
\endcode
Packit Service e31359
Packit Service e31359
  Compile... Ooops, forgot to declare the exception class. Let's do that:
Packit Service e31359
Packit Service e31359
<tt>Money.h</tt>
Packit Service e31359
\code
Packit Service e31359
#include <string>
Packit Service e31359
#include <stdexcept>
Packit Service e31359
Packit Service e31359
class IncompatibleMoneyError : public std::runtime_error
Packit Service e31359
{
Packit Service e31359
public:
Packit Service e31359
  IncompatibleMoneyError() : runtime_error( "Incompatible moneys" )
Packit Service e31359
  {
Packit Service e31359
  }
Packit Service e31359
};
Packit Service e31359
\endcode
Packit Service e31359
Packit Service e31359
  Compile. As expected testAddThrow() fail... Let's fix that:
Packit Service e31359
  
Packit Service e31359
<tt>Money.h</tt>
Packit Service e31359
\code
Packit Service e31359
  Money &operator +=( const Money &other )
Packit Service e31359
  {
Packit Service e31359
    if ( m_currency != other.m_currency )
Packit Service e31359
      throw IncompatibleMoneyError();
Packit Service e31359
Packit Service e31359
    m_amount += other.m_amount;
Packit Service e31359
    return *this;
Packit Service e31359
  }\endcode
Packit Service e31359
Packit Service e31359
  Compile. Our test finaly passes!
Packit Service e31359
Packit Service e31359
  TODO:
Packit Service e31359
- How to use CPPUNIT_ASSERT_EQUALS with Money
Packit Service e31359
- Copy constructor/Assignment operator
Packit Service e31359
- Introducing fixtures
Packit Service e31359
- ?
Packit Service e31359
Packit Service e31359
Packit Service e31359
  
Packit Service e31359
    
Packit Service e31359
      
Packit Service e31359
        
Packit Service e31359
\section sec_credits Credits
Packit Service e31359
This article was written by Baptiste Lepilleur. Unix configuration & set up 
Packit Service e31359
by Phil Verghese. Inspired from many others (JUnit, Phil's cookbook...), 
Packit Service e31359
and all the newbies around that keep asking me for the 
Packit Service e31359
'Hello world' example ;-)
Packit Service e31359
Packit Service e31359
Packit Service e31359
Packit Service e31359
*/