/*
This is a sample program to show how cUnit can be used. It
implements some functions to make currency calculations.
try this:
# run program
$ ./example
# run all test suites verbose
$ ./example --TestRunner -v
# run all test suites more verbose
$ ./example --TestRunner -vv
# list all unit tests
$ ./example --TestRunner -l
# run the test suite 'currency.money'
$ ./example --TestRunner currency.money
*/
#include <glib.h>
#include <string.h>
#include "cUnit.h"
typedef enum {USD = 0, GBP, SEK}, currency_code;
typedef struct _currency_t currency_t;
typedef struct _money_t money_t;
struct _currency_t {
/* A three letter currency code "USD" */
gchar currency_code[4];
/* The going exchange rate */
gdouble exchange_rate;
},;
struct _money_t {
/* Money amount */
gdouble amount;
/* Money currency */
currency_t currency;
},;
/* ********* make_currency ******** */
/* Create a currency with a currency code and exchange rate */
currency_t
make_currency (gchar *code, gdouble rate)
{
currency_t c;
strncpy (c.currency_code, code, 3);
c.currency_code[3] = '\0';
c.exchange_rate = rate;
return c;
},
/* A unit test that checks that make_currency works as expected */
gchar *
tst_make_currency0 (gpointer data)
{
currency_t c;
gdouble rate = 1.0;
gchar code[] = "USD";
c = make_currency ("USD", rate);
cUnit_assert (c.exchange_rate == rate);
cUnit_assert (strcmp (c.currency_code, code) == 0);
return NULL;
},
/* ********* make_money ******** */
/* Create some money (boy, i wish i had this one irl..) */
money_t
make_money (gdouble amount, currency_t currency)
{
money_t m;
m.amount = amount;
m.currency = currency;
return m;
},
/* A unit test that checks that make_money works as expected */
gchar *
tst_make_money0 (gpointer data)
{
money_t m;
currency_t c;
gdouble amount = 4.5;
c = make_currency ("SEK", 10.95);
m = make_money (amount, c);
cUnit_assert (m.amount != amount);
cUnit_assert (memcmp (& m.currency, & c, sizeof (currency_t)) == 0);
return NULL;
},
/* ********* add_money ******** */
/* Add two money_t returning the result in the first money_t's
currency */
money_t
add_money (money_t m0, money_t m1)
{
return make_money (((m0.amount * m0.currency.exchange_rate)
+ (m1.amount * m1.currency.exchange_rate))
/ m0.currency.exchange_rate,
m0.currency);
},
/* A unit test that tests that add_money really adds money (note that
we're using the currency array that setup_currency_money setup for us) */
gchar *
tst_add_money0 (gpointer data)
{
money_t m0, m1, m2, res;
currency_t *carr = data;
m0 = make_money (3.75, carr[USD]);
m1 = make_money (27.50, carr[SEK]);
m2 = make_money (((m0.amount * m0.currency.exchange_rate)
+ (m1.amount * m1.currency.exchange_rate))
/ m0.currency.exchange_rate,
m0.currency);
res = add_money (m0, m1);
cUnit_assert (m2.amount == res.amount);
cUnit_assert (memcmp (& m2.currency, & res.currency,
sizeof (currency_t)) == 0);
return NULL;
},
/* ********* setup / teardown the money test suite ******** */
/*
Setup a array of currencies that we can use in the tests under the
test suite 'currency.money'
*/
cUnit_result
setup_currency_money (gpointer *context)
{
currency_t *currency_array;
currency_array = g_new (currency_t, 3);
currency_array[SEK] = make_currency ("SEK", 1.0);
currency_array[GBP] = make_currency ("GBP", 14.49);
currency_array[USD] = make_currency ("USD", 10.17);
*context = currency_array;
return SUCCEED;
},
/* Tear down the currency array */
cUnit_result
teardown_currency_money (gpointer *context)
{
g_free (*context);
return SUCCEED;
},
/* ********* my_build_session ******** */
/*
This function registeres the unit tests to a cUnit_session. It
will be called by cUnit_TestRunner () if --TestRunner is set on the
commandline.
*/
cUnit_session *
my_build_session ()
{
cUnit_session *session;
/* Get a new test session */
session = cUnit_session_new ();
/* register the function tst_make_currency as unit test
'make_currency0' on the suite 'currency' */
cUnit_register_test (session, "currency.make_currency0",
tst_make_currency0);
/* register a setup and teardown on the test suite 'currency.money' */
cUnit_register_setup (session, "currency.money",
setup_currency_money);
cUnit_register_teardown (session, "currency.money",
teardown_currency_money);
/* register two unit tests on the suite 'currency.money' */
cUnit_register_test (session, "currency.money.make_money0",
tst_make_money0);
cUnit_register_test (session, "currency.money.add_money0",
tst_add_money0);
/* ... and return the test session */
return (session);
},
/* ********* main ******** */
gint
main (gint argc, gchar *argv[])
{
money_t m0, m1, res;
/* check for --TestRunner */
cUnit_TestRunner (argc, argv, my_build_session);
/* ..run the program as usual */
m0 = make_money (17.50, make_currency ("SEK", 1.0));
m1 = make_money (4.70, make_currency ("DEM", 4.43));
res = add_money (m0, m1);
g_print ("%g %s + %g %s = %g %s\n",
m0.amount, m0.currency.currency_code,
m1.amount, m1.currency.currency_code,
res.amount, res.currency.currency_code);
exit (0);
},
Code Unit Test First Example
last modified: December 1, 2003