From: <kt...@us...> - 2009-10-31 15:07:13
|
Revision: 3297 http://cutter.svn.sourceforge.net/cutter/?rev=3297&view=rev Author: ktou Date: 2009-10-31 15:07:03 +0000 (Sat, 31 Oct 2009) Log Message: ----------- * cutter/cut-loader.[ch], cutter/cut-repository.c, test/cutter/test-cut-loader.c, test/fixtures/loader/cpp-fixture/: support fixture functions detection defined in C++ namespace. Modified Paths: -------------- cutter/trunk/ChangeLog cutter/trunk/configure.ac cutter/trunk/cutter/cut-loader.c cutter/trunk/cutter/cut-loader.h cutter/trunk/cutter/cut-repository.c cutter/trunk/test/cutter/test-cut-loader.c cutter/trunk/test/fixtures/loader/Makefile.am Added Paths: ----------- cutter/trunk/test/fixtures/loader/cpp-fixture/ cutter/trunk/test/fixtures/loader/cpp-fixture/Makefile.am cutter/trunk/test/fixtures/loader/cpp-fixture/all.cpp cutter/trunk/test/fixtures/loader/cpp-fixture/with-prefix.cpp cutter/trunk/test/fixtures/loader/cpp-fixture/without-prefix.cpp Modified: cutter/trunk/ChangeLog =================================================================== --- cutter/trunk/ChangeLog 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/ChangeLog 2009-10-31 15:07:03 UTC (rev 3297) @@ -1,3 +1,10 @@ +2009-11-01 Kouhei Sutou <ko...@co...> + + * cutter/cut-loader.[ch], cutter/cut-repository.c, + test/cutter/test-cut-loader.c, + test/fixtures/loader/cpp-fixture/: support fixture functions + detection defined in C++ namespace. + 2009-10-31 Kouhei Sutou <ko...@co...> * cutter/cut-loader.c, Modified: cutter/trunk/configure.ac =================================================================== --- cutter/trunk/configure.ac 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/configure.ac 2009-10-31 15:07:03 UTC (rev 3297) @@ -632,6 +632,7 @@ test/fixtures/loader/suite/Makefile test/fixtures/loader/test/Makefile test/fixtures/loader/cpp/Makefile + test/fixtures/loader/cpp-fixture/Makefile test/fixtures/pipeline/Makefile test/fixtures/pipeline/error/Makefile test/fixtures/pipeline/failure/Makefile Modified: cutter/trunk/cutter/cut-loader.c =================================================================== --- cutter/trunk/cutter/cut-loader.c 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/cutter/cut-loader.c 2009-10-31 15:07:03 UTC (rev 3297) @@ -54,6 +54,7 @@ typedef struct _SymbolNames SymbolNames; struct _SymbolNames { + gchar *namespace; gchar *test_name; gchar *test_function_name; gchar *data_setup_function_name; @@ -87,7 +88,8 @@ G_DEFINE_TYPE (CutLoader, cut_loader, G_TYPE_OBJECT) static SymbolNames * -symbol_names_new (gchar *test_name, +symbol_names_new (gchar *namespace, + gchar *test_name, gchar *test_function_name, gchar *data_setup_function_name, gchar *attributes_setup_function_name, @@ -97,6 +99,7 @@ SymbolNames *names; names = g_new0(SymbolNames, 1); + names->namespace = namespace; names->test_name = test_name; names->test_function_name = test_function_name; names->data_setup_function_name = data_setup_function_name; @@ -110,6 +113,7 @@ static void symbol_names_free (SymbolNames *names) { + g_free(names->namespace); g_free(names->test_name); g_free(names->test_function_name); g_free(names->data_setup_function_name); @@ -378,6 +382,7 @@ gchar *data_setup_function_name = NULL; gchar *attributes_setup_function_name = NULL; gboolean require_data_setup_function = FALSE; + gchar *namespace; GString *test_name; test_name = g_string_new(NULL); @@ -389,7 +394,7 @@ name = test_name_start + test_name_length; if (g_str_equal(name, "Ev")) { - } else if (g_str_equal(name, "EPv")) { + } else if (g_str_equal(name, "EPv") || g_str_equal(name, "EPKv")) { GString *data_setup_function_name_string; size_t test_name_prefix_length; @@ -434,8 +439,14 @@ g_string_free(attributes_setup_function_name_string, FALSE); } + if (test_name->len == 0) { + namespace = g_strdup(""); + } else { + namespace = g_strndup(test_name->str, test_name->len - 2); + } g_string_append_len(test_name, test_name_start, test_name_length); - return symbol_names_new(g_string_free(test_name, FALSE), + return symbol_names_new(namespace, + g_string_free(test_name, FALSE), g_strdup(original_name), data_setup_function_name, attributes_setup_function_name, @@ -461,8 +472,9 @@ g_strconcat(ATTRIBUTES_SETUP_FUNCTION_NAME_PREFIX, name + strlen(TEST_NAME_PREFIX), NULL); - return symbol_names_new(g_strdup(name), + return symbol_names_new(NULL, g_strdup(name), + g_strdup(name), data_setup_function_name, attributes_setup_function_name, FALSE, @@ -877,6 +889,28 @@ g_object_unref(test); } +static const gchar * +mangle (GString *buffer, const gchar *namespace, const gchar *function) +{ + gchar **components, **component; + + if (!namespace) + return function; + + g_string_assign(buffer, "_ZN"); + components = g_strsplit(namespace, "::", 0); + for (component = components; *component; component++) { + g_string_append_printf(buffer, "%" G_GSIZE_FORMAT "%s", + strlen(*component), *component); + } + g_strfreev(components); + g_string_append_printf(buffer, "%" G_GSIZE_FORMAT "%s", + strlen(function), function); + g_string_append(buffer, "Ev"); + + return buffer->str; +} + static void cb_complete (CutTestCase *test_case, CutTestContext *test_context, gboolean success, gpointer data) @@ -886,7 +920,7 @@ } static CutTestCase * -create_test_case (CutLoader *loader) +create_test_case (CutLoader *loader, const gchar *namespace) { CutLoaderPrivate *priv; CutTestCase *test_case; @@ -895,19 +929,29 @@ CutShutdownFunction shutdown = NULL; CutTeardownFunction teardown = NULL; gchar *test_case_name, *filename; + GString *buffer; priv = CUT_LOADER_GET_PRIVATE(loader); + buffer = g_string_new(NULL); +#define MANGLE(function_name) \ + mangle(buffer, namespace, function_name) #define GET_HOOK_FUNCTION(name) \ - if (!g_module_symbol(priv->module, "cut_" #name, (gpointer)&name)) \ - g_module_symbol(priv->module, #name, (gpointer)&name) + if (!g_module_symbol(priv->module, MANGLE("cut_" #name), (gpointer)&name)) \ + g_module_symbol(priv->module, MANGLE(#name), (gpointer)&name) GET_HOOK_FUNCTION(setup); GET_HOOK_FUNCTION(teardown); - g_module_symbol(priv->module, "cut_startup", (gpointer)&startup); - g_module_symbol(priv->module, "cut_shutdown", (gpointer)&shutdown); - + if (namespace) { + GET_HOOK_FUNCTION(startup); + GET_HOOK_FUNCTION(shutdown); + } else { + g_module_symbol(priv->module, MANGLE("cut_startup"), (gpointer)&startup); + g_module_symbol(priv->module, MANGLE("cut_shutdown"), (gpointer)&shutdown); + } #undef GET_HOOK_FUNCTION +#undef MANGLE + g_string_free(buffer, TRUE); filename = g_path_get_basename(priv->so_filename); if (g_str_has_prefix(filename, "lib")) { @@ -932,13 +976,60 @@ return test_case; } -CutTestCase * -cut_loader_load_test_case (CutLoader *loader) +typedef struct _LoadTestCaseData { + CutLoader *loader; + GList *test_cases; +} LoadTestCaseData; + +static gboolean +load_test_case (gpointer key, gpointer value, gpointer user_data) +{ + const gchar *namespace = key; + GList *test_names = value; + LoadTestCaseData *data = user_data; + GList *node; + CutTestCase *test_case; + + test_case = create_test_case(data->loader, namespace); + for (node = test_names; node; node = g_list_next(node)) { + SymbolNames *names = node->data; + register_valid_test(data->loader, test_case, names); + } + g_list_free(test_names); + data->test_cases = g_list_append(data->test_cases, test_case); + + return TRUE; +} + +static guint +string_hash_safe (gconstpointer value) +{ + if (!value) + return 0; + + return g_str_hash(value); +} + +static gboolean +string_equal_safe (gconstpointer value1, gconstpointer value2) +{ + const gchar *string1 = value1; + const gchar *string2 = value2; + + if (string1 == string2) + return TRUE; + return g_str_equal(string1, string2); +} + +GList * +cut_loader_load_test_cases (CutLoader *loader) +{ CutLoaderPrivate *priv; GList *node; GList *test_names; - CutTestCase *test_case; + GHashTable *grouped_test_names; + LoadTestCaseData data; priv = CUT_LOADER_GET_PRIVATE(loader); if (!priv->so_filename) @@ -978,15 +1069,42 @@ if (!test_names) return NULL; - test_case = create_test_case(loader); + grouped_test_names = g_hash_table_new(string_hash_safe, string_equal_safe); for (node = test_names; node; node = g_list_next(node)) { SymbolNames *names = node->data; + GList *test_name_list; - register_valid_test(loader, test_case, names); - symbol_names_free(names); + test_name_list = g_hash_table_lookup(grouped_test_names, + names->namespace); + test_name_list = g_list_append(test_name_list, names); + g_hash_table_insert(grouped_test_names, names->namespace, + test_name_list); } + data.loader = loader; + data.test_cases = NULL; + g_hash_table_foreach_remove(grouped_test_names, load_test_case, &data); + g_hash_table_destroy(grouped_test_names); + + g_list_foreach(test_names, (GFunc)symbol_names_free, NULL); g_list_free(test_names); + return data.test_cases; +} + +CutTestCase * +cut_loader_load_test_case (CutLoader *loader) +{ + GList* test_cases; + CutTestCase* test_case; + + test_cases = cut_loader_load_test_cases(loader); + if (!test_cases) + return NULL; + + test_case = test_cases->data; + g_list_foreach(g_list_next(test_cases), (GFunc)g_object_unref, NULL); + g_list_free(test_cases); + return test_case; } Modified: cutter/trunk/cutter/cut-loader.h =================================================================== --- cutter/trunk/cutter/cut-loader.h 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/cutter/cut-loader.h 2009-10-31 15:07:03 UTC (rev 3297) @@ -62,6 +62,7 @@ const gchar *cut_loader_get_base_directory(CutLoader *loader); void cut_loader_set_base_directory(CutLoader *loader, const gchar *base_directory); +GList *cut_loader_load_test_cases (CutLoader *loader); CutTestCase *cut_loader_load_test_case (CutLoader *loader); CutTestSuite *cut_loader_load_test_suite (CutLoader *loader); Modified: cutter/trunk/cutter/cut-repository.c =================================================================== --- cutter/trunk/cutter/cut-repository.c 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/cutter/cut-repository.c 2009-10-31 15:07:03 UTC (rev 3297) @@ -354,13 +354,16 @@ for (list = priv->loaders; list; list = g_list_next(list)) { CutLoader *loader = CUT_LOADER(list->data); - CutTestCase *test_case; + GList *test_cases, *node; - test_case = cut_loader_load_test_case(loader); - if (test_case) { + test_cases = cut_loader_load_test_cases(loader); + for (node = test_cases; node; node = g_list_next(node)) { + CutTestCase *test_case = node->data; + cut_test_suite_add_test_case(suite, test_case); g_object_unref(test_case); } + g_list_free(test_cases); } return suite; } Modified: cutter/trunk/test/cutter/test-cut-loader.c =================================================================== --- cutter/trunk/test/cutter/test-cut-loader.c 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/test/cutter/test-cut-loader.c 2009-10-31 15:07:03 UTC (rev 3297) @@ -16,6 +16,8 @@ void test_fail_to_load (void); void test_load_test_iterator (void); void test_load_cpp_namespace (void); +void data_cpp_fixture_function (void); +void test_cpp_fixture_function (gconstpointer data); static CutLoader *loader; static CutTestCase *test_case; @@ -343,6 +345,98 @@ cut_assert_equal_string_array(expected_functions, test_names); } +static const gchar * +mangle (const gchar *component, ...) +{ + GString *mangled; + va_list args; + + mangled = g_string_new("_ZN"); + va_start(args, component); + while (component) { + g_string_append_printf(mangled, + "%" G_GSIZE_FORMAT "%s", + strlen(component), component); + component = va_arg(args, gchar *); + } + va_end(args); + g_string_append(mangled, "Ev"); + + return cut_take_string(g_string_free(mangled, FALSE)); +} + +void +data_cpp_fixture_function (void) +{ + data_fixture_function(); +} + +void +test_cpp_fixture_function (gconstpointer data) +{ + const FixtureTestData *test_data = data; + CutStartupFunction expected_startup_function = NULL; + CutStartupFunction actual_startup_function = NULL; + CutShutdownFunction expected_shutdown_function = NULL; + CutShutdownFunction actual_shutdown_function = NULL; + CutSetupFunction expected_setup_function = NULL; + CutSetupFunction actual_setup_function = NULL; + CutTeardownFunction expected_teardown_function = NULL; + CutTeardownFunction actual_teardown_function = NULL; + gchar *so_filename; + + loader = loader_new("cpp-fixture", test_data->file_name); + test_case = cut_loader_load_test_case(loader); + cut_assert(test_case); + + g_object_get(G_OBJECT(loader), + "so-filename", &so_filename, + NULL); + module = g_module_open(so_filename, + G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + g_free(so_filename); + cut_assert_not_null(module); + if (test_data->startup_function_name) + cut_assert_true(g_module_symbol(module, + mangle("fixture", + test_data->startup_function_name, + NULL), + (gpointer)&expected_startup_function)); + if (test_data->setup_function_name) + cut_assert_true(g_module_symbol(module, + mangle("fixture", + test_data->setup_function_name, + NULL), + (gpointer)&expected_setup_function)); + if (test_data->teardown_function_name) + cut_assert_true(g_module_symbol(module, + mangle("fixture", + test_data->teardown_function_name, + NULL), + (gpointer)&expected_teardown_function)); + if (test_data->shutdown_function_name) + cut_assert_true(g_module_symbol(module, + mangle("fixture", + test_data->shutdown_function_name, + NULL), + (gpointer)&expected_shutdown_function)); + + g_object_get(G_OBJECT(test_case), + "startup-function", &actual_startup_function, + "setup-function", &actual_setup_function, + "teardown-function", &actual_teardown_function, + "shutdown-function", &actual_shutdown_function, + NULL); + cut_assert_equal_pointer(expected_startup_function, + actual_startup_function); + cut_assert_equal_pointer(expected_setup_function, + actual_setup_function); + cut_assert_equal_pointer(expected_teardown_function, + actual_teardown_function); + cut_assert_equal_pointer(expected_shutdown_function, + actual_shutdown_function); +} + /* vi:ts=4:nowrap:ai:expandtab:sw=4 */ Modified: cutter/trunk/test/fixtures/loader/Makefile.am =================================================================== --- cutter/trunk/test/fixtures/loader/Makefile.am 2009-10-31 13:38:08 UTC (rev 3296) +++ cutter/trunk/test/fixtures/loader/Makefile.am 2009-10-31 15:07:03 UTC (rev 3297) @@ -5,4 +5,5 @@ module \ suite \ test \ - cpp + cpp \ + cpp-fixture Property changes on: cutter/trunk/test/fixtures/loader/cpp-fixture ___________________________________________________________________ Added: svn:ignore + .deps Makefile.in Makefile Added: cutter/trunk/test/fixtures/loader/cpp-fixture/Makefile.am =================================================================== --- cutter/trunk/test/fixtures/loader/cpp-fixture/Makefile.am (rev 0) +++ cutter/trunk/test/fixtures/loader/cpp-fixture/Makefile.am 2009-10-31 15:07:03 UTC (rev 3297) @@ -0,0 +1,29 @@ +INCLUDES = \ + $(CUTTER_CFLAGS) \ + -I$(top_builddir) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/cutter \ + -I$(top_srcdir)/gcutter \ + -I$(top_srcdir)/cppcutter + +noinst_LTLIBRARIES = \ + with-prefix.la \ + without-prefix.la \ + all.la + +AM_LDFLAGS = \ + -module \ + -rpath $(libdir) \ + -avoid-version \ + -no-undefined + +LIBS = \ + $(top_builddir)/cutter/libcutter.la \ + $(top_builddir)/gcutter/libgcutter.la \ + $(top_builddir)/cppcutter/libcppcutter.la \ + $(GLIB_LIBS) + +with_prefix_la_SOURCES = with-prefix.cpp +without_prefix_la_SOURCES = without-prefix.cpp +all_la_SOURCES = all.cpp + Added: cutter/trunk/test/fixtures/loader/cpp-fixture/all.cpp =================================================================== --- cutter/trunk/test/fixtures/loader/cpp-fixture/all.cpp (rev 0) +++ cutter/trunk/test/fixtures/loader/cpp-fixture/all.cpp 2009-10-31 15:07:03 UTC (rev 3297) @@ -0,0 +1,72 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2009 Kouhei Sutou <ko...@cl...> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <cppcutter.h> + +namespace fixture +{ + void + cut_startup (void) + { + } + + void + startup (void) + { + } + + void + cut_setup (void) + { + } + + void + setup (void) + { + } + + void + test_nothing (void) + { + } + + void + teardown (void) + { + } + + void + cut_teardown (void) + { + } + + void + shutdown (void) + { + } + + void + cut_shutdown (void) + { + } +} + +/* +vi:ts=4:nowrap:ai:expandtab:sw=4 +*/ Property changes on: cutter/trunk/test/fixtures/loader/cpp-fixture/all.cpp ___________________________________________________________________ Added: svn:keywords + Id Added: cutter/trunk/test/fixtures/loader/cpp-fixture/with-prefix.cpp =================================================================== --- cutter/trunk/test/fixtures/loader/cpp-fixture/with-prefix.cpp (rev 0) +++ cutter/trunk/test/fixtures/loader/cpp-fixture/with-prefix.cpp 2009-10-31 15:07:03 UTC (rev 3297) @@ -0,0 +1,52 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2009 Kouhei Sutou <ko...@cl...> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <cppcutter.h> + +namespace fixture +{ + void + cut_startup (void) + { + } + + void + cut_setup (void) + { + } + + void + test_nothing (void) + { + } + + void + cut_teardown (void) + { + } + + void + cut_shutdown (void) + { + } +} + +/* +vi:ts=4:nowrap:ai:expandtab:sw=4 +*/ Property changes on: cutter/trunk/test/fixtures/loader/cpp-fixture/with-prefix.cpp ___________________________________________________________________ Added: svn:keywords + Id Added: cutter/trunk/test/fixtures/loader/cpp-fixture/without-prefix.cpp =================================================================== --- cutter/trunk/test/fixtures/loader/cpp-fixture/without-prefix.cpp (rev 0) +++ cutter/trunk/test/fixtures/loader/cpp-fixture/without-prefix.cpp 2009-10-31 15:07:03 UTC (rev 3297) @@ -0,0 +1,52 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2009 Kouhei Sutou <ko...@cl...> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <cppcutter.h> + +namespace fixture +{ + void + startup (void) + { + } + + void + setup (void) + { + } + + void + test_nothing (void) + { + } + + void + teardown (void) + { + } + + void + shutdown (void) + { + } +} + +/* +vi:ts=4:nowrap:ai:expandtab:sw=4 +*/ Property changes on: cutter/trunk/test/fixtures/loader/cpp-fixture/without-prefix.cpp ___________________________________________________________________ Added: svn:keywords + Id This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |