/* 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 #include #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); }