| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // ================================================================================
- // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås ==
- // == See tb_core.h for more information. ==
- // ================================================================================
- #include "tb_test.h"
- #include "tb_system.h"
- #ifdef TB_UNIT_TESTING
- // Reference at least one group in each test file, to force
- // linking the object file. This is needed if TB is compiled
- // as an library.
- TB_FORCE_LINK_TEST_GROUP(tb_color);
- TB_FORCE_LINK_TEST_GROUP(tb_dimension_converter);
- TB_FORCE_LINK_TEST_GROUP(tb_geometry);
- TB_FORCE_LINK_TEST_GROUP(tb_linklist);
- TB_FORCE_LINK_TEST_GROUP(tb_node_ref_tree);
- TB_FORCE_LINK_TEST_GROUP(tb_object);
- TB_FORCE_LINK_TEST_GROUP(tb_parser);
- TB_FORCE_LINK_TEST_GROUP(tb_space_allocator);
- TB_FORCE_LINK_TEST_GROUP(tb_editfield);
- TB_FORCE_LINK_TEST_GROUP(tb_tempbuffer);
- TB_FORCE_LINK_TEST_GROUP(tb_test);
- TB_FORCE_LINK_TEST_GROUP(tb_value);
- TB_FORCE_LINK_TEST_GROUP(tb_widget_value_text);
- #endif
- namespace tb {
- #ifdef TB_UNIT_TESTING
- uint32 test_settings;
- int fail_line_nr;
- const char *fail_file;
- const char *fail_text;
- // We can't use a linked list object since we don't know if its constructor
- // would run before of after any test group constructor that add itself
- // to it. Using a manual one way link list is very simple.
- TBTestGroup *g_test_groups = nullptr;
- // == Misc functions ==========================================================
- TBStr tb_get_test_file_name(const char *testpath, const char *filename)
- {
- TBStr str;
- int test_path_len = strlen(testpath);
- for (int i = test_path_len - 1; i > 0 && testpath[i] != '/' && testpath[i] != '\\'; i--)
- test_path_len = i;
- str.Set(testpath, test_path_len);
- str.Append(filename);
- return str;
- }
- // == TBRegisterCall ==========================================================
- TBRegisterCall::TBRegisterCall(TBTestGroup *test, TBCall *call)
- : call(call)
- {
- if (strcmp(call->name(), "Setup") == 0)
- test->setup = call;
- else if (strcmp(call->name(), "Cleanup") == 0)
- test->cleanup = call;
- else if (strcmp(call->name(), "Init") == 0)
- test->init = call;
- else if (strcmp(call->name(), "Shutdown") == 0)
- test->shutdown = call;
- else
- test->calls.AddLast(call);
- }
- TBRegisterCall::~TBRegisterCall()
- {
- if (call->linklist)
- call->linklist->Remove(call);
- }
- // == TBTestGroup =============================================================
- TBTestGroup::TBTestGroup(const char *name)
- : name(name), setup(nullptr), cleanup(nullptr), init(nullptr), shutdown(nullptr), next_test_group(g_test_groups)
- {
- g_test_groups = this;
- }
- const char *CallAndOutput(TBTestGroup *test, TBCall *call)
- {
- fail_text = nullptr;
- call->exec();
- if (!fail_text)
- return fail_text;
- TBStr msg;
- msg.SetFormatted("FAIL: \"%s/%s\":\n"
- " %s(%d): \"%s\"\n",
- test->name, call->name(),
- fail_file, fail_line_nr, fail_text);
- TBDebugOut(msg);
- return fail_text;
- }
- void OutputPass(TBTestGroup *test, const char *call_name)
- {
- if (!(test_settings & TB_TEST_VERBOSE))
- return;
- TBStr msg;
- msg.SetFormatted("PASS: \"%s/%s\"\n",
- test->name, call_name);
- TBDebugOut(msg);
- }
- int TBRunTests(uint32 settings)
- {
- test_settings = settings;
- int num_failed = 0;
- int num_passed = 0;
- TBDebugOut("Running tests...\n");
- for (TBTestGroup *group = g_test_groups; group; group = group->next_test_group)
- {
- if (group->init && CallAndOutput(group, group->init))
- {
- // The whole group failed because init failed.
- int num_tests_in_group = 0;
- for (TBCall *call = group->calls.GetFirst(); call; call = call->GetNext())
- if (!group->IsSpecialTest(call))
- num_tests_in_group++;
- TBStr msg;
- msg.SetFormatted(" %d tests skipped.\n", num_tests_in_group);
- TBDebugOut(msg);
- num_failed += num_tests_in_group;
- continue;
- }
- for (TBCall *call = group->calls.GetFirst(); call; call = call->GetNext())
- {
- // Execute test (and call setup and cleanup if available).
- int fail = 0;
- if (group->setup)
- fail = !!CallAndOutput(group, group->setup);
- if (!fail) // Only run if setup succeeded
- {
- fail |= !!CallAndOutput(group, call);
- if (group->cleanup)
- fail |= !!CallAndOutput(group, group->cleanup);
- }
- // Handle result
- if (fail)
- num_failed++;
- else
- {
- num_passed++;
- OutputPass(group, call->name());
- }
- }
- if (group->shutdown && CallAndOutput(group, group->shutdown))
- CallAndOutput(group, group->shutdown);
- }
- TBStr msg;
- msg.SetFormatted("Test results: %d passed, %d failed.\n", num_passed, num_failed);
- TBDebugOut(msg);
- return num_failed;
- }
- #endif // TB_UNIT_TESTING
- }; // namespace tb
|