summaryrefslogtreecommitdiff
path: root/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/core/test-eval.cpp203
-rw-r--r--tests/unit/core/test-hashtable.cpp140
-rw-r--r--tests/unit/core/test-hdata.cpp118
-rw-r--r--tests/unit/core/test-infolist.cpp114
-rw-r--r--tests/unit/core/test-list.cpp118
-rw-r--r--tests/unit/core/test-string.cpp710
-rw-r--r--tests/unit/core/test-url.cpp51
-rw-r--r--tests/unit/core/test-utf8.cpp336
-rw-r--r--tests/unit/core/test-util.cpp168
9 files changed, 1958 insertions, 0 deletions
diff --git a/tests/unit/core/test-eval.cpp b/tests/unit/core/test-eval.cpp
new file mode 100644
index 000000000..131bd8959
--- /dev/null
+++ b/tests/unit/core/test-eval.cpp
@@ -0,0 +1,203 @@
+/*
+ * test-eval.cpp - test evaluation functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include <stdio.h>
+#include "../src/core/wee-eval.h"
+#include "../src/core/wee-config.h"
+#include "../src/core/wee-hashtable.h"
+#include "../src/core/wee-version.h"
+#include "../src/plugins/plugin.h"
+}
+
+#define WEE_CHECK_EVAL(__result, __expr) \
+ value = eval_expression (__expr, NULL, extra_vars, NULL); \
+ STRCMP_EQUAL(__result, value); \
+ free (value);
+#define WEE_CHECK_EVAL_COND(__result, __expr) \
+ value = eval_expression (__expr, NULL, extra_vars, options); \
+ STRCMP_EQUAL(__result, value); \
+ free (value);
+
+TEST_GROUP(Eval)
+{
+};
+
+/*
+ * Tests functions:
+ * eval_is_true
+ */
+
+TEST(Eval, Boolean)
+{
+ /* false */
+ LONGS_EQUAL(0, eval_is_true (NULL));
+ LONGS_EQUAL(0, eval_is_true (""));
+ LONGS_EQUAL(0, eval_is_true ("0"));
+
+ /* true */
+ LONGS_EQUAL(1, eval_is_true ("00"));
+ LONGS_EQUAL(1, eval_is_true ("1"));
+ LONGS_EQUAL(1, eval_is_true ("A"));
+ LONGS_EQUAL(1, eval_is_true ("abcdef"));
+}
+
+/*
+ * Tests functions:
+ * eval_expression (condition)
+ */
+
+TEST(Eval, EvalCondition)
+{
+ struct t_hashtable *extra_vars, *options;
+ char *value;
+
+ extra_vars = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ hashtable_set (extra_vars, "test", "value");
+ CHECK(extra_vars);
+
+ options = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ hashtable_set (options, "type", "condition");
+ CHECK(options);
+
+ POINTERS_EQUAL(NULL, eval_expression (NULL, NULL, NULL, options));
+
+ /* conditions evaluated as false */
+ WEE_CHECK_EVAL_COND("0", "");
+ WEE_CHECK_EVAL_COND("0", "0");
+ WEE_CHECK_EVAL_COND("0", "1 == 2");
+ WEE_CHECK_EVAL_COND("0", "1 >= 2");
+ WEE_CHECK_EVAL_COND("0", "2 <= 1");
+ WEE_CHECK_EVAL_COND("0", "2 != 2");
+ WEE_CHECK_EVAL_COND("0", "18 < 5");
+ WEE_CHECK_EVAL_COND("0", "5 > 18");
+ WEE_CHECK_EVAL_COND("0", "1 == 5 > 18");
+ WEE_CHECK_EVAL_COND("0", "abc == def");
+ WEE_CHECK_EVAL_COND("0", "()");
+ WEE_CHECK_EVAL_COND("0", "(5 > 26)");
+ WEE_CHECK_EVAL_COND("0", "((5 > 26))");
+ WEE_CHECK_EVAL_COND("0", "(26 < 5)");
+ WEE_CHECK_EVAL_COND("0", "abc > def");
+ WEE_CHECK_EVAL_COND("0", "1 && 0");
+ WEE_CHECK_EVAL_COND("0", "abc && 0");
+ WEE_CHECK_EVAL_COND("0", "0 || 0");
+ WEE_CHECK_EVAL_COND("0", "0 || 0 || 0");
+ WEE_CHECK_EVAL_COND("0", "0 || 1 && 0");
+ WEE_CHECK_EVAL_COND("0", "0 || (1 && 0)");
+ WEE_CHECK_EVAL_COND("0", "0 || (0 || (1 && 0))");
+ WEE_CHECK_EVAL_COND("0", "1 && (0 || 0)");
+ WEE_CHECK_EVAL_COND("0", "(0 || 1) && 0");
+ WEE_CHECK_EVAL_COND("0", "((0 || 1) && 1) && 0");
+ WEE_CHECK_EVAL_COND("0", "abcd =~ (?-i)^ABC");
+ WEE_CHECK_EVAL_COND("0", "abcd =~ \\(abcd\\)");
+ WEE_CHECK_EVAL_COND("0", "(abcd) =~ \\(\\(abcd\\)\\)");
+ WEE_CHECK_EVAL_COND("0", "${test} == test");
+ WEE_CHECK_EVAL_COND("0", "${test2} == value2");
+ WEE_CHECK_EVAL_COND("0", "${buffer.number} == 2");
+ WEE_CHECK_EVAL_COND("0", "${window.buffer.number} == 2");
+
+ /* conditions evaluated as true */
+ WEE_CHECK_EVAL_COND("1", "1");
+ WEE_CHECK_EVAL_COND("1", "123");
+ WEE_CHECK_EVAL_COND("1", "abc");
+ WEE_CHECK_EVAL_COND("1", "2 == 2");
+ WEE_CHECK_EVAL_COND("1", "2 >= 1");
+ WEE_CHECK_EVAL_COND("1", "1 <= 2");
+ WEE_CHECK_EVAL_COND("1", "1 != 2");
+ WEE_CHECK_EVAL_COND("1", "18 > 5");
+ WEE_CHECK_EVAL_COND("1", "5 < 18");
+ WEE_CHECK_EVAL_COND("1", "1 == 18 > 5");
+ WEE_CHECK_EVAL_COND("1", "abc == abc");
+ WEE_CHECK_EVAL_COND("1", "(26 > 5)");
+ WEE_CHECK_EVAL_COND("1", "((26 > 5))");
+ WEE_CHECK_EVAL_COND("1", "(5 < 26)");
+ WEE_CHECK_EVAL_COND("1", "def > abc");
+ WEE_CHECK_EVAL_COND("1", "1 && 1");
+ WEE_CHECK_EVAL_COND("1", "abc && 1");
+ WEE_CHECK_EVAL_COND("1", "0 || 1");
+ WEE_CHECK_EVAL_COND("1", "0 || 0 || 1");
+ WEE_CHECK_EVAL_COND("1", "1 || 1 && 0");
+ WEE_CHECK_EVAL_COND("1", "0 || (1 && 1)");
+ WEE_CHECK_EVAL_COND("1", "0 || (0 || (1 && 1))");
+ WEE_CHECK_EVAL_COND("1", "1 && (0 || 1)");
+ WEE_CHECK_EVAL_COND("1", "(0 || 1) && 1");
+ WEE_CHECK_EVAL_COND("1", "((0 || 1) && 1) && 1");
+ WEE_CHECK_EVAL_COND("1", "abcd =~ ^ABC");
+ WEE_CHECK_EVAL_COND("1", "abcd =~ (?-i)^abc");
+ WEE_CHECK_EVAL_COND("1", "(abcd) =~ (abcd)");
+ WEE_CHECK_EVAL_COND("1", "(abcd) =~ \\(abcd\\)");
+ WEE_CHECK_EVAL_COND("1", "((abcd)) =~ \\(\\(abcd\\)\\)");
+ WEE_CHECK_EVAL_COND("1", "${test} == value");
+ WEE_CHECK_EVAL_COND("1", "${test2} ==");
+ WEE_CHECK_EVAL_COND("1", "${buffer.number} == 1");
+ WEE_CHECK_EVAL_COND("1", "${window.buffer.number} == 1");
+
+ hashtable_free (extra_vars);
+ hashtable_free (options);
+}
+
+/*
+ * Tests functions:
+ * eval_expression (expression)
+ */
+
+TEST(Eval, EvalExpression)
+{
+ struct t_hashtable *extra_vars;
+ char *value, str_value[256];
+ void *toto;
+
+ extra_vars = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ hashtable_set (extra_vars, "test", "value");
+ CHECK(extra_vars);
+
+ POINTERS_EQUAL(NULL, eval_expression (NULL, NULL, NULL, NULL));
+ WEE_CHECK_EVAL("", "");
+ WEE_CHECK_EVAL("a b c", "a b c");
+ WEE_CHECK_EVAL("$", "$");
+ WEE_CHECK_EVAL("", "${");
+ WEE_CHECK_EVAL("}", "}");
+ WEE_CHECK_EVAL("", "${}");
+ WEE_CHECK_EVAL("", "${xyz}");
+ WEE_CHECK_EVAL("\t", "${\\t}");
+ WEE_CHECK_EVAL(version_get_version (), "${info:version}");
+ WEE_CHECK_EVAL("1", "${buffer.number}");
+ WEE_CHECK_EVAL("1", "${window.buffer.number}");
+ WEE_CHECK_EVAL("core.weechat", "${buffer.full_name}");
+ WEE_CHECK_EVAL("core.weechat", "${window.buffer.full_name}");
+ snprintf (str_value, sizeof (str_value),
+ "%d", CONFIG_INTEGER(config_look_scroll_amount));
+ WEE_CHECK_EVAL(str_value, "${weechat.look.scroll_amount}");
+
+ hashtable_free (extra_vars);
+}
diff --git a/tests/unit/core/test-hashtable.cpp b/tests/unit/core/test-hashtable.cpp
new file mode 100644
index 000000000..a7c35fab0
--- /dev/null
+++ b/tests/unit/core/test-hashtable.cpp
@@ -0,0 +1,140 @@
+/*
+ * test-hashtable.cpp - test hashtable functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include "../src/core/wee-hashtable.h"
+}
+
+TEST_GROUP(Hashtable)
+{
+};
+
+/*
+ * Tests functions:
+ * hashtable_hash_key_djb2
+ */
+
+TEST(Hashtable, HashDbj2)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_new
+ */
+
+TEST(Hashtable, New)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_set_with_size
+ * hashtable_set
+ */
+
+TEST(Hashtable, Set)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_get_item
+ * hashtable_get
+ * hashtable_has_key
+ */
+
+TEST(Hashtable, Get)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_map
+ * hashtable_map_string
+ */
+
+TEST(Hashtable, Map)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_dup
+ */
+
+TEST(Hashtable, Dup)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_get_list_keys
+ * hashtable_get_integer
+ * hashtable_get_string
+ * hashtable_set_pointer
+ */
+
+TEST(Hashtable, Properties)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_add_to_infolist
+ */
+
+TEST(Hashtable, Infolist)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_remove
+ * hashtable_remove_all
+ * hashtable_free
+ */
+
+TEST(Hashtable, Free)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hashtable_print_log
+ */
+
+TEST(Hashtable, PrintLog)
+{
+ /* TODO: write tests */
+}
diff --git a/tests/unit/core/test-hdata.cpp b/tests/unit/core/test-hdata.cpp
new file mode 100644
index 000000000..31af084a0
--- /dev/null
+++ b/tests/unit/core/test-hdata.cpp
@@ -0,0 +1,118 @@
+/*
+ * test-hdata.cpp - test hdata functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include "../src/core/wee-hdata.h"
+}
+
+TEST_GROUP(Hdata)
+{
+};
+
+/*
+ * Tests functions:
+ * hdata_new
+ * hdata_new_var
+ * hdata_new_list
+ */
+
+TEST(Hdata, New)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hdata_get_var_offset
+ * hdata_get_var_type
+ * hdata_get_var_type_string
+ * hdata_get_var_array_size
+ * hdata_get_var_array_size_string
+ * hdata_get_var_hdata
+ * hdata_get_var
+ * hdata_get_var_at_offset
+ * hdata_get_list
+ */
+
+TEST(Hdata, Get)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hdata_check_pointer
+ */
+
+TEST(Hdata, Check)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hdata_move
+ * hdata_search
+ */
+
+TEST(Hdata, Move)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hdata_char
+ * hdata_integer
+ * hdata_long
+ * hdata_string
+ * hdata_pointer
+ * hdata_time
+ */
+
+TEST(Hdata, Read)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hdata_free_all_plugin
+ * hdata_free_all
+ */
+
+TEST(Hdata, Free)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * hdata_print_log
+ */
+
+TEST(Hdata, PrintLog)
+{
+ /* TODO: write tests */
+}
diff --git a/tests/unit/core/test-infolist.cpp b/tests/unit/core/test-infolist.cpp
new file mode 100644
index 000000000..6b7a67c11
--- /dev/null
+++ b/tests/unit/core/test-infolist.cpp
@@ -0,0 +1,114 @@
+/*
+ * test-infolist.cpp - test infolist functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include "../src/core/wee-infolist.h"
+}
+
+TEST_GROUP(Infolist)
+{
+};
+
+/*
+ * Tests functions:
+ * infolist_new
+ * infolist_new_item
+ * infolist_new_var_integer
+ * infolist_new_var_string
+ * infolist_new_var_pointer
+ * infolist_new_var_buffer
+ * infolist_new_var_time
+ */
+
+TEST(Infolist, New)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * infolist_valid
+ */
+
+TEST(Infolist, Valid)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * infolist_search_var
+ */
+
+TEST(Infolist, Search)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * infolist_next
+ * infolist_prev
+ * infolist_reset_item_cursor
+ */
+
+TEST(Infolist, Move)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * infolist_integer
+ * infolist_string
+ * infolist_pointer
+ * infolist_buffer
+ * infolist_time
+ */
+
+TEST(Infolist, Get)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * infolist_free
+ * infolist_free_all_plugin
+ */
+
+TEST(Infolist, Free)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * infolist_print_log
+ */
+
+TEST(Infolist, PrintLog)
+{
+ /* TODO: write tests */
+}
diff --git a/tests/unit/core/test-list.cpp b/tests/unit/core/test-list.cpp
new file mode 100644
index 000000000..7e804c1f2
--- /dev/null
+++ b/tests/unit/core/test-list.cpp
@@ -0,0 +1,118 @@
+/*
+ * test-list.cpp - test list functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include "../src/core/wee-list.h"
+}
+
+TEST_GROUP(List)
+{
+};
+
+/*
+ * Tests functions:
+ * weelist_new
+ */
+
+TEST(List, New)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_add
+ */
+
+TEST(List, Add)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_search
+ * weelist_search_pos
+ * weelist_casesearch
+ * weelist_casesearch_pos
+ */
+
+TEST(List, Search)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_get
+ * weelist_string
+ */
+
+TEST(List, Get)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_set
+ */
+
+TEST(List, Set)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_next
+ * weelist_prev
+ */
+
+TEST(List, Move)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_remove
+ * weelist_remove_all
+ * weelist_free
+ */
+
+TEST(List, Free)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weelist_print_log
+ */
+
+TEST(List, PrintLog)
+{
+ /* TODO: write tests */
+}
diff --git a/tests/unit/core/test-string.cpp b/tests/unit/core/test-string.cpp
new file mode 100644
index 000000000..f430d870d
--- /dev/null
+++ b/tests/unit/core/test-string.cpp
@@ -0,0 +1,710 @@
+/*
+ * test-string.cpp - test string functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include <stdio.h>
+#include <string.h>
+#include <regex.h>
+#include "../src/core/wee-string.h"
+}
+
+#define WEE_HAS_HL_STR(__result, __str, __words) \
+ LONGS_EQUAL(__result, string_has_highlight (__str, __words));
+
+#define WEE_HAS_HL_REGEX(__result_regex, __result_hl, __str, __regex) \
+ LONGS_EQUAL(__result_hl, \
+ string_has_highlight_regex (__str, __regex)); \
+ LONGS_EQUAL(__result_regex, \
+ string_regcomp (&regex, __regex, REG_ICASE)); \
+ if (__result_regex == 0) \
+ { \
+ LONGS_EQUAL(__result_hl, \
+ string_has_highlight_regex_compiled (__str, \
+ &regex)); \
+ regfree(&regex); \
+ } \
+
+#define WEE_HAS_HL_REGEX_COMP(__result, __str, __regex) \
+
+
+TEST_GROUP(String)
+{
+};
+
+/*
+ * Tests functions:
+ * string_strndup
+ */
+
+TEST(String, Duplicate)
+{
+ const char *str_test = "test";
+ char *str;
+
+ str = string_strndup (NULL, 0);
+
+ str = string_strndup (str_test, 0);
+ CHECK(str);
+ CHECK(str != str_test);
+ STRCMP_EQUAL(str, "");
+ free (str);
+
+ str = string_strndup (str_test, 2);
+ CHECK(str);
+ CHECK(str != str_test);
+ STRCMP_EQUAL(str, "te");
+ free (str);
+
+ str = string_strndup (str_test, 500);
+ CHECK(str);
+ CHECK(str != str_test);
+ STRCMP_EQUAL(str, str_test);
+ free (str);
+}
+
+/*
+ * Tests functions:
+ * string_tolower
+ * string_toupper
+ */
+
+TEST(String, Case)
+{
+ char *str;
+
+ str = strdup ("ABC");
+
+ string_tolower (str);
+ STRCMP_EQUAL("abc", str);
+ string_toupper (str);
+ STRCMP_EQUAL("ABC", str);
+
+ free (str);
+}
+
+/*
+ * Tests functions:
+ * string_strcasecmp
+ * string_strncasecmp
+ * string_strcasecmp_range
+ * string_strncasecmp_range
+ * string_strcmp_ignore_chars
+ */
+
+TEST(String, Comparison)
+{
+ /* case-insensitive comparison */
+ LONGS_EQUAL(0, string_strcasecmp (NULL, NULL));
+ LONGS_EQUAL(-1, string_strcasecmp (NULL, "abc"));
+ LONGS_EQUAL(1, string_strcasecmp ("abc", NULL));
+ LONGS_EQUAL(0, string_strcasecmp ("abc", "abc"));
+ LONGS_EQUAL(0, string_strcasecmp ("abc", "ABC"));
+ LONGS_EQUAL(0, string_strcasecmp ("ABC", "ABC"));
+ LONGS_EQUAL(-1, string_strcasecmp ("abc", "def"));
+ LONGS_EQUAL(-1, string_strcasecmp ("abc", "DEF"));
+ LONGS_EQUAL(-1, string_strcasecmp ("ABC", "def"));
+ LONGS_EQUAL(-1, string_strcasecmp ("ABC", "DEF"));
+ LONGS_EQUAL(1, string_strcasecmp ("def", "abc"));
+ LONGS_EQUAL(1, string_strcasecmp ("def", "ABC"));
+ LONGS_EQUAL(1, string_strcasecmp ("DEF", "abc"));
+ LONGS_EQUAL(1, string_strcasecmp ("DEF", "ABC"));
+
+ /* case-insensitive comparison with max length */
+ LONGS_EQUAL(0, string_strncasecmp (NULL, NULL, 3));
+ LONGS_EQUAL(-1, string_strncasecmp (NULL, "abc", 3));
+ LONGS_EQUAL(1, string_strncasecmp ("abc", NULL, 3));
+ LONGS_EQUAL(0, string_strncasecmp ("abc", "abc", 3));
+ LONGS_EQUAL(0, string_strncasecmp ("abcabc", "abcdef", 3));
+ LONGS_EQUAL(-1, string_strncasecmp ("abcabc", "abcdef", 6));
+ LONGS_EQUAL(0, string_strncasecmp ("abc", "ABC", 3));
+ LONGS_EQUAL(0, string_strncasecmp ("abcabc", "ABCDEF", 3));
+ LONGS_EQUAL(-1, string_strncasecmp ("abcabc", "ABCDEF", 6));
+ LONGS_EQUAL(0, string_strncasecmp ("ABC", "ABC", 3));
+ LONGS_EQUAL(0, string_strncasecmp ("ABCABC", "ABCDEF", 3));
+ LONGS_EQUAL(-1, string_strncasecmp ("ABCABC", "ABCDEF", 6));
+ LONGS_EQUAL(-1, string_strncasecmp ("abc", "def", 3));
+ LONGS_EQUAL(-1, string_strncasecmp ("abc", "DEF", 3));
+ LONGS_EQUAL(-1, string_strncasecmp ("ABC", "def", 3));
+ LONGS_EQUAL(-1, string_strncasecmp ("ABC", "DEF", 3));
+ LONGS_EQUAL(1, string_strncasecmp ("def", "abc", 3));
+ LONGS_EQUAL(1, string_strncasecmp ("def", "ABC", 3));
+ LONGS_EQUAL(1, string_strncasecmp ("DEF", "abc", 3));
+ LONGS_EQUAL(1, string_strncasecmp ("DEF", "ABC", 3));
+
+ /* case-insensitive comparison with a range */
+ LONGS_EQUAL(0, string_strcasecmp_range (NULL, NULL, 30));
+ LONGS_EQUAL(-1, string_strcasecmp_range (NULL, "abc", 30));
+ LONGS_EQUAL(1, string_strcasecmp_range ("abc", NULL, 30));
+ LONGS_EQUAL(-1, string_strcasecmp_range ("A", "Z", 30));
+ LONGS_EQUAL(1, string_strcasecmp_range ("Z", "A", 30));
+ LONGS_EQUAL(0, string_strcasecmp_range ("A", "a", 30));
+ LONGS_EQUAL(-1, string_strcasecmp_range ("ë", "€", 30));
+ LONGS_EQUAL(0, string_strcasecmp_range ("[", "{", 30));
+ LONGS_EQUAL(0, string_strcasecmp_range ("]", "}", 30));
+ LONGS_EQUAL(0, string_strcasecmp_range ("\\", "|", 30));
+ LONGS_EQUAL(0, string_strcasecmp_range ("^", "~", 30));
+ LONGS_EQUAL(-1, string_strcasecmp_range ("[", "{", 26));
+ LONGS_EQUAL(-1, string_strcasecmp_range ("]", "}", 26));
+ LONGS_EQUAL(-1, string_strcasecmp_range ("\\", "|", 26));
+ LONGS_EQUAL(-1, string_strcasecmp_range ("^", "~", 26));
+
+ /* case-insensitive comparison with max length and a range */
+ LONGS_EQUAL(0, string_strncasecmp_range (NULL, NULL, 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range (NULL, "abc", 3, 30));
+ LONGS_EQUAL(1, string_strncasecmp_range ("abc", NULL, 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("ABC", "ZZZ", 3, 30));
+ LONGS_EQUAL(1, string_strncasecmp_range ("ZZZ", "ABC", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("ABC", "abc", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("ABCABC", "abcdef", 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("ABCABC", "abcdef", 6, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("ëëë", "€€€", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("[[[", "{{{", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("[[[abc", "{{{def", 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("[[[abc", "{{{def", 6, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("]]]", "}}}", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("]]]abc", "}}}def", 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("]]]abc", "}}}def", 6, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("\\\\\\", "|||", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("\\\\\\abc", "|||def", 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("\\\\\\abc", "|||def", 6, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("^^^", "~~~", 3, 30));
+ LONGS_EQUAL(0, string_strncasecmp_range ("^^^abc", "~~~def", 3, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("^^^abc", "~~~def", 6, 30));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("[[[", "{{{", 3, 26));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("]]]", "}}}", 3, 26));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("\\\\\\", "|||", 3, 26));
+ LONGS_EQUAL(-1, string_strncasecmp_range ("^^^", "~~~", 3, 26));
+
+ /* comparison with chars ignored */
+ LONGS_EQUAL(0, string_strcmp_ignore_chars (NULL, NULL, "", 0));
+ LONGS_EQUAL(-1, string_strcmp_ignore_chars (NULL, "abc", "", 0));
+ LONGS_EQUAL(1, string_strcmp_ignore_chars ("abc", NULL, "", 0));
+ LONGS_EQUAL(-1, string_strcmp_ignore_chars ("ABC", "ZZZ", "", 0));
+ LONGS_EQUAL(1, string_strcmp_ignore_chars ("ZZZ", "ABC", "", 0));
+ LONGS_EQUAL(0, string_strcmp_ignore_chars ("ABC", "abc", "", 0));
+ LONGS_EQUAL(-1, string_strcmp_ignore_chars ("ABC", "abc", "", 1));
+ LONGS_EQUAL(0, string_strcmp_ignore_chars ("abc..abc", "abcabc", ".", 0));
+ LONGS_EQUAL(1, string_strcmp_ignore_chars ("abc..abc", "ABCABC", ".", 1));
+ LONGS_EQUAL(0, string_strcmp_ignore_chars ("abc..abc", "abc-.-.abc",
+ ".-", 0));
+ LONGS_EQUAL(1, string_strcmp_ignore_chars ("abc..abc", "ABC-.-.ABC",
+ ".-", 1));
+}
+
+/*
+ * Tests functions:
+ * string_strcasestr
+ */
+
+TEST(String, Search)
+{
+ const char *str = "test";
+
+ /* case-insensitive search of string in a string */
+ POINTERS_EQUAL(NULL, string_strcasestr (NULL, NULL));
+ POINTERS_EQUAL(NULL, string_strcasestr (NULL, str));
+ POINTERS_EQUAL(NULL, string_strcasestr (str, NULL));
+ POINTERS_EQUAL(NULL, string_strcasestr (str, ""));
+ POINTERS_EQUAL(NULL, string_strcasestr (str, "zz"));
+ POINTERS_EQUAL(str + 1, string_strcasestr (str, "est"));
+ POINTERS_EQUAL(str + 1, string_strcasestr (str, "EST"));
+}
+
+/*
+ * Tests functions:
+ * string_match
+ */
+
+TEST(String, Match)
+{
+ LONGS_EQUAL(0, string_match (NULL, NULL, 0));
+ LONGS_EQUAL(0, string_match (NULL, "test", 0));
+ LONGS_EQUAL(0, string_match ("test", NULL, 0));
+ LONGS_EQUAL(0, string_match ("", "", 0));
+ LONGS_EQUAL(0, string_match ("", "test", 0));
+ LONGS_EQUAL(0, string_match ("test", "", 0));
+ LONGS_EQUAL(0, string_match ("test", "def", 0));
+ LONGS_EQUAL(0, string_match ("test", "def", 1));
+ LONGS_EQUAL(0, string_match ("test", "def*", 0));
+ LONGS_EQUAL(0, string_match ("test", "def*", 1));
+ LONGS_EQUAL(0, string_match ("test", "*def", 0));
+ LONGS_EQUAL(0, string_match ("test", "*def", 1));
+ LONGS_EQUAL(0, string_match ("test", "*def*", 0));
+ LONGS_EQUAL(0, string_match ("test", "*def*", 1));
+ LONGS_EQUAL(0, string_match ("test", "def", 0));
+ LONGS_EQUAL(0, string_match ("test", "def", 1));
+ LONGS_EQUAL(0, string_match ("test", "es", 0));
+ LONGS_EQUAL(0, string_match ("test", "es", 1));
+ LONGS_EQUAL(0, string_match ("test", "es*", 0));
+ LONGS_EQUAL(0, string_match ("test", "es*", 1));
+ LONGS_EQUAL(0, string_match ("test", "*es", 0));
+ LONGS_EQUAL(0, string_match ("test", "*es", 1));
+ LONGS_EQUAL(1, string_match ("test", "*es*", 0));
+ LONGS_EQUAL(1, string_match ("test", "*es*", 1));
+ LONGS_EQUAL(1, string_match ("test", "*ES*", 0));
+ LONGS_EQUAL(0, string_match ("test", "*ES*", 1));
+}
+
+/*
+ * Tests functions:
+ * string_expand_home
+ */
+
+TEST(String, ExpandHome)
+{
+ char *home, *result;
+ int length_home;
+
+ home = getenv ("HOME");
+ length_home = strlen (home);
+
+ result = string_expand_home("~/abc.txt");
+ CHECK(strncmp (result, home, length_home) == 0);
+ LONGS_EQUAL(length_home + 8, strlen (result));
+ STRCMP_EQUAL(result + length_home, "/abc.txt");
+ free (result);
+}
+
+/*
+ * Tests functions:
+ * string_remove_quotes
+ */
+
+TEST(String, RemoveQuotes)
+{
+ POINTERS_EQUAL(NULL, string_remove_quotes (NULL, NULL));
+ POINTERS_EQUAL(NULL, string_remove_quotes (NULL, "abc"));
+ POINTERS_EQUAL(NULL, string_remove_quotes ("abc", NULL));
+ STRCMP_EQUAL("", string_remove_quotes("", ""));
+ STRCMP_EQUAL("", string_remove_quotes("", "\"'"));
+ STRCMP_EQUAL("abc", string_remove_quotes("abc", "\"'"));
+ STRCMP_EQUAL(" abc ", string_remove_quotes(" abc ", "\"'"));
+ STRCMP_EQUAL("abc", string_remove_quotes("'abc'", "\"'"));
+ STRCMP_EQUAL("abc", string_remove_quotes(" 'abc' ", "\"'"));
+ STRCMP_EQUAL("'abc'", string_remove_quotes("\"'abc'\"", "\"'"));
+ STRCMP_EQUAL("'abc'", string_remove_quotes(" \"'abc'\" ", "\"'"));
+ STRCMP_EQUAL("'a'b'c'", string_remove_quotes("\"'a'b'c'\"", "\"'"));
+ STRCMP_EQUAL("'a'b'c'", string_remove_quotes(" \"'a'b'c'\" ", "\"'"));
+}
+
+/*
+ * Tests functions:
+ * string_strip
+ */
+
+TEST(String, Strip)
+{
+ POINTERS_EQUAL(NULL, string_strip (NULL, 1, 1, NULL));
+ POINTERS_EQUAL(NULL, string_strip (NULL, 1, 1, ".;"));
+ STRCMP_EQUAL("test", string_strip ("test", 1, 1, NULL));
+ STRCMP_EQUAL("test", string_strip ("test", 1, 1, ".;"));
+ STRCMP_EQUAL(".-test.-", string_strip (".-test.-", 0, 0, ".-"));
+ STRCMP_EQUAL("test", string_strip (".-test.-", 1, 1, ".-"));
+ STRCMP_EQUAL("test.-", string_strip (".-test.-", 1, 0, ".-"));
+ STRCMP_EQUAL(".-test", string_strip (".-test.-", 0, 1, ".-"));
+}
+
+/*
+ * Tests functions:
+ * string_convert_escaped_chars
+ */
+
+TEST(String, ConvertEscapedChars)
+{
+ POINTERS_EQUAL(NULL, string_convert_escaped_chars (NULL));
+ STRCMP_EQUAL("", string_convert_escaped_chars (""));
+ STRCMP_EQUAL("\"", string_convert_escaped_chars ("\\\""));
+ STRCMP_EQUAL("\\", string_convert_escaped_chars ("\\\\"));
+ STRCMP_EQUAL("\a", string_convert_escaped_chars ("\\a"));
+ STRCMP_EQUAL("\a", string_convert_escaped_chars ("\\a"));
+ STRCMP_EQUAL("\b", string_convert_escaped_chars ("\\b"));
+ STRCMP_EQUAL("\e", string_convert_escaped_chars ("\\e"));
+ STRCMP_EQUAL("\f", string_convert_escaped_chars ("\\f"));
+ STRCMP_EQUAL("\n", string_convert_escaped_chars ("\\n"));
+ STRCMP_EQUAL("\r", string_convert_escaped_chars ("\\r"));
+ STRCMP_EQUAL("\t", string_convert_escaped_chars ("\\t"));
+ STRCMP_EQUAL("\v", string_convert_escaped_chars ("\\v"));
+ STRCMP_EQUAL("\123", string_convert_escaped_chars ("\\0123"));
+ STRCMP_EQUAL("\123",
+ string_convert_escaped_chars ("\\0123")); /* invalid */
+ STRCMP_EQUAL("\x41", string_convert_escaped_chars ("\\x41"));
+ STRCMP_EQUAL("\x04z", string_convert_escaped_chars ("\\x4z"));
+ STRCMP_EQUAL("\u0012zz", string_convert_escaped_chars ("\\u12zz"));
+ STRCMP_EQUAL("\U00123456", string_convert_escaped_chars ("\\U00123456"));
+ STRCMP_EQUAL("\U00000123zzz",
+ string_convert_escaped_chars ("\\U00123zzz"));
+ STRCMP_EQUAL("",
+ string_convert_escaped_chars ("\\U12345678")); /* invalid */
+}
+
+/*
+ * Tests functions:
+ * string_is_word_char
+ */
+
+/*
+TEST(String, IsWordChar)
+{
+ LONGS_EQUAL(0, string_is_word_char (NULL));
+ LONGS_EQUAL(0, string_is_word_char (""));
+ LONGS_EQUAL(0, string_is_word_char ("&abc"));
+ LONGS_EQUAL(0, string_is_word_char ("+abc"));
+ LONGS_EQUAL(0, string_is_word_char ("$abc"));
+ LONGS_EQUAL(0, string_is_word_char ("*abc"));
+ LONGS_EQUAL(0, string_is_word_char ("/abc"));
+
+ LONGS_EQUAL(1, string_is_word_char ("abc"));
+ LONGS_EQUAL(1, string_is_word_char ("-abc"));
+ LONGS_EQUAL(1, string_is_word_char ("_abc"));
+ LONGS_EQUAL(1, string_is_word_char ("|abc"));
+}
+*/
+
+/*
+ * Tests functions:
+ * string_mask_to_regex
+ */
+
+TEST(String, MaskToRegex)
+{
+ POINTERS_EQUAL(NULL, string_mask_to_regex (NULL));
+ STRCMP_EQUAL("", string_mask_to_regex (""));
+ STRCMP_EQUAL("test", string_mask_to_regex ("test"));
+ STRCMP_EQUAL("test.*", string_mask_to_regex ("test*"));
+ STRCMP_EQUAL(".*test.*", string_mask_to_regex ("*test*"));
+ STRCMP_EQUAL(".*te.*st.*", string_mask_to_regex ("*te*st*"));
+ STRCMP_EQUAL("test\\.\\[\\]\\{\\}\\(\\)\\?\\+\\|\\^\\$\\\\",
+ string_mask_to_regex ("test.[]{}()?+|^$\\"));
+}
+
+/*
+ * Tests functions:
+ * string_regex_flags
+ * string_regcomp
+ */
+
+TEST(String, Regex)
+{
+ int flags, rc;
+ const char *ptr;
+ regex_t regex;
+
+ string_regex_flags (NULL, 0, NULL);
+ string_regex_flags ("", 0, NULL);
+
+ string_regex_flags (NULL, 0, &flags);
+ LONGS_EQUAL(0, flags);
+ string_regex_flags ("", 0, &flags);
+ LONGS_EQUAL(0, flags);
+ string_regex_flags (NULL, REG_EXTENDED, &flags);
+ LONGS_EQUAL(REG_EXTENDED, flags);
+ string_regex_flags ("", REG_EXTENDED, &flags);
+ LONGS_EQUAL(REG_EXTENDED, flags);
+
+ ptr = string_regex_flags ("test", REG_EXTENDED, &flags);
+ LONGS_EQUAL(REG_EXTENDED, flags);
+ STRCMP_EQUAL("test", ptr);
+
+ string_regex_flags ("(?e)test", 0, &flags);
+ LONGS_EQUAL(REG_EXTENDED, flags);
+ STRCMP_EQUAL("test", ptr);
+
+ string_regex_flags ("(?ei)test", 0, &flags);
+ LONGS_EQUAL(REG_EXTENDED | REG_ICASE, flags);
+ STRCMP_EQUAL("test", ptr);
+
+ string_regex_flags ("(?eins)test", 0, &flags);
+ LONGS_EQUAL(REG_EXTENDED | REG_ICASE | REG_NEWLINE | REG_NOSUB, flags);
+ STRCMP_EQUAL("test", ptr);
+
+ string_regex_flags ("(?ins)test", REG_EXTENDED, &flags);
+ LONGS_EQUAL(REG_EXTENDED | REG_ICASE | REG_NEWLINE | REG_NOSUB, flags);
+ STRCMP_EQUAL("test", ptr);
+
+ string_regex_flags ("(?ins-e)test", REG_EXTENDED, &flags);
+ LONGS_EQUAL(REG_ICASE | REG_NEWLINE | REG_NOSUB, flags);
+ STRCMP_EQUAL("test", ptr);
+
+ /* compile regular expression */
+ LONGS_EQUAL(-1, string_regcomp (&regex, NULL, 0));
+ LONGS_EQUAL(0, string_regcomp (&regex, "", 0));
+ regfree (&regex);
+ LONGS_EQUAL(0, string_regcomp (&regex, "test", 0));
+ regfree (&regex);
+ LONGS_EQUAL(0, string_regcomp (&regex, "test", REG_EXTENDED));
+ regfree (&regex);
+ LONGS_EQUAL(0, string_regcomp (&regex, "(?ins)test", REG_EXTENDED));
+ regfree (&regex);
+}
+
+/*
+ * Tests functions:
+ * string_has_highlight
+ * string_has_highlight_regex_compiled
+ * string_has_highlight_regex
+ */
+
+TEST(String, Highlight)
+{
+ regex_t regex;
+
+ /* check highlight with a string */
+ WEE_HAS_HL_STR(0, NULL, NULL);
+ WEE_HAS_HL_STR(0, NULL, "");
+ WEE_HAS_HL_STR(0, "", NULL);
+ WEE_HAS_HL_STR(0, "", "");
+ WEE_HAS_HL_STR(0, "test", "");
+ WEE_HAS_HL_STR(0, "", "test");
+ WEE_HAS_HL_STR(1, "test", "test");
+ WEE_HAS_HL_STR(1, "this is a test", "test");
+ WEE_HAS_HL_STR(1, "test here", "test");
+ WEE_HAS_HL_STR(1, "this is a test here", "test");
+ WEE_HAS_HL_STR(0, "this is a test here", "abc,def");
+ WEE_HAS_HL_STR(1, "this is a test here", "abc,test");
+
+ /*
+ * check highlight with a regex, each call of macro
+ * checks with a regex as string, and then a compiled regex
+ */
+ WEE_HAS_HL_REGEX(-1, 0, NULL, NULL);
+ WEE_HAS_HL_REGEX(0, 0, NULL, "");
+ WEE_HAS_HL_REGEX(-1, 0, "", NULL);
+ WEE_HAS_HL_REGEX(0, 0, "", "");
+ WEE_HAS_HL_REGEX(0, 0, "test", "");
+ WEE_HAS_HL_REGEX(0, 0, "", "test");
+ WEE_HAS_HL_REGEX(0, 1, "test", "test");
+ WEE_HAS_HL_REGEX(0, 1, "this is a test", "test");
+ WEE_HAS_HL_REGEX(0, 1, "abc tested", "test.*");
+ WEE_HAS_HL_REGEX(0, 1, "abc tested here", "test.*");
+ WEE_HAS_HL_REGEX(0, 1, "tested here", "test.*");
+ WEE_HAS_HL_REGEX(0, 0, "this is a test", "teste.*");
+ WEE_HAS_HL_REGEX(0, 0, "test here", "teste.*");
+}
+
+/*
+ * Tests functions:
+ * string_replace
+ * string_replace_regex
+ * string_replace_with_callback
+ */
+
+TEST(String, Replace)
+{
+ POINTERS_EQUAL(NULL, string_replace (NULL, NULL, NULL));
+ POINTERS_EQUAL(NULL, string_replace ("string", NULL, NULL));
+ POINTERS_EQUAL(NULL, string_replace (NULL, "search", NULL));
+ POINTERS_EQUAL(NULL, string_replace (NULL, NULL, "replace"));
+ POINTERS_EQUAL(NULL, string_replace ("string", "search", NULL));
+ POINTERS_EQUAL(NULL, string_replace ("string", NULL, "replace"));
+ POINTERS_EQUAL(NULL, string_replace (NULL, "search", "replace"));
+
+ STRCMP_EQUAL("test abc def", string_replace("test abc def", "xyz", "xxx"));
+ STRCMP_EQUAL("test xxx def", string_replace("test abc def", "abc", "xxx"));
+ STRCMP_EQUAL("xxx test xxx def xxx",
+ string_replace("abc test abc def abc", "abc", "xxx"));
+}
+
+/*
+ * Tests functions:
+ * string_split
+ * string_split_shared
+ * string_split_shell
+ * string_free_split
+ * string_free_split_shared
+ * string_build_with_split_string
+ * string_split_command
+ * string_free_split_command
+ */
+
+TEST(String, Split)
+{
+ char **argv, *str;
+ int argc;
+
+ POINTERS_EQUAL(NULL, string_split (NULL, NULL, 0, 0, NULL));
+ POINTERS_EQUAL(NULL, string_split (NULL, "", 0, 0, NULL));
+ POINTERS_EQUAL(NULL, string_split ("", NULL, 0, 0, NULL));
+ POINTERS_EQUAL(NULL, string_split ("", "", 0, 0, NULL));
+
+ argc = 1;
+ POINTERS_EQUAL(NULL, string_split (NULL, NULL, 0, 0, &argc));
+ LONGS_EQUAL(0, argc);
+ argc = 1;
+ POINTERS_EQUAL(NULL, string_split (NULL, "", 0, 0, &argc));
+ LONGS_EQUAL(0, argc);
+ argc = 1;
+ POINTERS_EQUAL(NULL, string_split ("", NULL, 0, 0, &argc));
+ LONGS_EQUAL(0, argc);
+ argc = 1;
+ POINTERS_EQUAL(NULL, string_split ("", "", 0, 0, &argc));
+ LONGS_EQUAL(0, argc);
+
+ /* free split with NULL */
+ string_free_split (NULL);
+ string_free_split_shared (NULL);
+ string_free_split_command (NULL);
+
+ /* standard split */
+ argv = string_split (" abc de fghi ", " ", 0, 0, &argc);
+ LONGS_EQUAL(3, argc);
+ STRCMP_EQUAL("abc", argv[0]);
+ STRCMP_EQUAL("de", argv[1]);
+ STRCMP_EQUAL("fghi", argv[2]);
+ POINTERS_EQUAL(NULL, argv[3]);
+ string_free_split (argv);
+
+ /* max 2 items */
+ argv = string_split (" abc de fghi ", " ", 0, 2, &argc);
+ LONGS_EQUAL(2, argc);
+ STRCMP_EQUAL("abc", argv[0]);
+ STRCMP_EQUAL("de", argv[1]);
+ POINTERS_EQUAL(NULL, argv[2]);
+ string_free_split (argv);
+
+ /* keep eol */
+ argv = string_split (" abc de fghi ", " ", 1, 0, &argc);
+ LONGS_EQUAL(3, argc);
+ STRCMP_EQUAL("abc de fghi", argv[0]);
+ STRCMP_EQUAL("de fghi", argv[1]);
+ STRCMP_EQUAL("fghi", argv[2]);
+ POINTERS_EQUAL(NULL, argv[3]);
+ string_free_split (argv);
+
+ /* keep eol and max 2 items */
+ argv = string_split (" abc de fghi ", " ", 1, 2, &argc);
+ LONGS_EQUAL(2, argc);
+ STRCMP_EQUAL("abc de fghi", argv[0]);
+ STRCMP_EQUAL("de fghi", argv[1]);
+ POINTERS_EQUAL(NULL, argv[2]);
+ string_free_split (argv);
+
+ /* split with shared strings */
+ argv = string_split_shared (" abc de abc ", " ", 0, 0, &argc);
+ LONGS_EQUAL(3, argc);
+ STRCMP_EQUAL("abc", argv[0]);
+ STRCMP_EQUAL("de", argv[1]);
+ STRCMP_EQUAL("abc", argv[2]);
+ POINTERS_EQUAL(NULL, argv[3]);
+ /* same content == same pointer for shared strings */
+ POINTERS_EQUAL(argv[0], argv[2]);
+ string_free_split_shared (argv);
+
+ /* build string with split string */
+ str = string_build_with_split_string (NULL, NULL);
+ POINTERS_EQUAL(NULL, str);
+ argv = string_split (" abc de fghi ", " ", 0, 0, &argc);
+ str = string_build_with_split_string ((const char **)argv, NULL);
+ STRCMP_EQUAL("abcdefghi", str);
+ free (str);
+ str = string_build_with_split_string ((const char **)argv, "");
+ STRCMP_EQUAL("abcdefghi", str);
+ free (str);
+ str = string_build_with_split_string ((const char **)argv, ";;");
+ STRCMP_EQUAL("abc;;de;;fghi", str);
+ free (str);
+ string_free_split (argv);
+
+ /* split command */
+ POINTERS_EQUAL(NULL, string_split_command (NULL, ';'));
+ POINTERS_EQUAL(NULL, string_split_command ("", ';'));
+ argv = string_split_command ("abc;de;fghi", ';');
+ LONGS_EQUAL(3, argc);
+ STRCMP_EQUAL("abc", argv[0]);
+ STRCMP_EQUAL("de", argv[1]);
+ STRCMP_EQUAL("fghi", argv[2]);
+ POINTERS_EQUAL(NULL, argv[3]);
+ string_free_split_command (argv);
+}
+
+/*
+ * Tests functions:
+ * string_iconv
+ * string_iconv_to_internal
+ * string_iconv_from_internal
+ * string_iconv_fprintf
+ */
+
+TEST(String, Iconv)
+{
+ const char *noel_utf8 = "no\xc3\xabl"; /* noël */
+ const char *noel_iso = "no\xebl";
+ char *str;
+
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * string_format_size
+ */
+
+TEST(String, FormatSize)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * string_encode_base16
+ * string_decode_base16
+ * string_encode_base64
+ * string_decode_base64
+ */
+
+TEST(String, BaseN)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * string_is_command_char
+ * string_input_for_buffer
+ */
+
+TEST(String, Input)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * string_is_command_char
+ */
+
+TEST(String, CommandChar)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * string_shared_get
+ * string_shared_free
+ */
+
+TEST(String, Shared)
+{
+ /* TODO: write tests */
+}
diff --git a/tests/unit/core/test-url.cpp b/tests/unit/core/test-url.cpp
new file mode 100644
index 000000000..5401af156
--- /dev/null
+++ b/tests/unit/core/test-url.cpp
@@ -0,0 +1,51 @@
+/*
+ * test-url.cpp - test URL functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include "../src/core/wee-url.h"
+}
+
+TEST_GROUP(Url)
+{
+};
+
+/*
+ * Tests functions:
+ * weeurl_download
+ */
+
+TEST(Url, Download)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * weeurl_option_add_to_infolist
+ */
+
+TEST(Url, AddToInfolist)
+{
+ /* TODO: write tests */
+}
diff --git a/tests/unit/core/test-utf8.cpp b/tests/unit/core/test-utf8.cpp
new file mode 100644
index 000000000..6f226c91c
--- /dev/null
+++ b/tests/unit/core/test-utf8.cpp
@@ -0,0 +1,336 @@
+/*
+ * test-utf8.cpp - test UTF-8 string functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include <stdio.h>
+#include <string.h>
+#include <wctype.h>
+#include "../src/core/wee-utf8.h"
+}
+
+#define WEE_CHECK_STRNDUP(__result, __string, __length) \
+ str = utf8_strndup (__string, __length); \
+ STRCMP_EQUAL(__result, str); \
+ free (str);
+
+const char *noel_valid = "no\xc3\xabl"; /* noël */
+const char *noel_invalid = "no\xc3l";
+const char *noel_invalid2 = "no\xff\xffl";
+const char *noel_invalid_norm = "no?l";
+const char *noel_invalid2_norm = "no??l";
+const char *han_char = "\xf0\xa4\xad\xa2"; /* U+24B62 */
+const char *han_char_z = "\xf0\xa4\xad\xa2Z";
+
+TEST_GROUP(Utf8)
+{
+};
+
+/*
+ * Tests functions:
+ * utf8_has_8bits
+ * utf8_is_valid
+ */
+
+TEST(Utf8, Validity)
+{
+ char *error;
+
+ /* check 8 bits */
+ LONGS_EQUAL(0, utf8_has_8bits (NULL));
+ LONGS_EQUAL(0, utf8_has_8bits (""));
+ LONGS_EQUAL(0, utf8_has_8bits ("abc"));
+ LONGS_EQUAL(1, utf8_has_8bits ("no\xc3\xabl"));
+
+ /* check validity */
+ LONGS_EQUAL(1, utf8_is_valid (NULL, NULL));
+ LONGS_EQUAL(1, utf8_is_valid (NULL, &error));
+ LONGS_EQUAL(1, utf8_is_valid ("", NULL));
+ LONGS_EQUAL(1, utf8_is_valid ("", &error));
+ LONGS_EQUAL(1, utf8_is_valid ("abc", &error));
+ POINTERS_EQUAL(NULL, error);
+ LONGS_EQUAL(1, utf8_is_valid (noel_valid, &error));
+ POINTERS_EQUAL(NULL, error);
+ LONGS_EQUAL(0, utf8_is_valid (noel_invalid, &error));
+ POINTERS_EQUAL(noel_invalid + 2, error);
+
+ /* 2 bytes: code point must be in range U+0080-07FF */
+ //LONGS_EQUAL(0, utf8_is_valid ("\xc0\x80", NULL)); /* U+0 */
+ //LONGS_EQUAL(0, utf8_is_valid ("\xc1\xbf", NULL)); /* U+7F */
+ LONGS_EQUAL(1, utf8_is_valid ("\xc2\x80", NULL)); /* U+80 */
+ LONGS_EQUAL(1, utf8_is_valid ("\xdf\xbf", NULL)); /* U+7FF */
+
+ /* 3 bytes: code point must be in range: U+0800-FFFF */
+ //LONGS_EQUAL(0, utf8_is_valid ("\xe0\x80\x80", NULL)); /* U+0 */
+ //LONGS_EQUAL(0, utf8_is_valid ("\xe0\x9f\xbf", NULL)); /* U+7FF */
+ LONGS_EQUAL(1, utf8_is_valid ("\xe0\xa0\x80", NULL)); /* U+800 */
+ LONGS_EQUAL(1, utf8_is_valid ("\xef\xbf\xbf", NULL)); /* U+FFFF */
+
+ /* 4 bytes: code point must be in range: U+10000-1FFFFF */
+ //LONGS_EQUAL(0, utf8_is_valid ("\xf0\x80\x80\x80", NULL)); /* U+0 */
+ //LONGS_EQUAL(0, utf8_is_valid ("\xf0\x8f\xbf\xbf", NULL)); /* U+FFFF */
+ LONGS_EQUAL(1, utf8_is_valid ("\xf0\x90\x80\x80", NULL)); /* U+10000 */
+ LONGS_EQUAL(1, utf8_is_valid ("\xf7\xbf\xbf\xbf", NULL)); /* U+1FFFFF */
+}
+
+/*
+ * Tests functions:
+ * utf8_normalize
+ */
+
+TEST(Utf8, Normalize)
+{
+ char *str;
+
+ str = strdup (noel_invalid);
+ utf8_normalize (NULL, '?');
+ utf8_normalize (str, '?');
+ STRCMP_EQUAL(noel_invalid_norm, str);
+ free (str);
+
+ str = strdup (noel_invalid2);
+ utf8_normalize (str, '?');
+ STRCMP_EQUAL(noel_invalid2_norm, str);
+ free (str);
+}
+
+/*
+ * Tests functions:
+ * utf8_prev_char
+ * utf8_next_char
+ * utf8_add_offset
+ * utf8_real_pos
+ * utf8_pos
+ */
+
+TEST(Utf8, Move)
+{
+ char *ptr;
+
+ /* previous/next char */
+ POINTERS_EQUAL(NULL, utf8_prev_char (NULL, NULL));
+ POINTERS_EQUAL(NULL, utf8_next_char (NULL));
+ ptr = utf8_next_char (noel_valid);
+ STRCMP_EQUAL("oël", ptr);
+ ptr = utf8_next_char (ptr);
+ STRCMP_EQUAL("ël", ptr);
+ ptr = utf8_next_char (ptr);
+ STRCMP_EQUAL("l", ptr);
+ ptr = utf8_prev_char (noel_valid, ptr);
+ ptr = utf8_prev_char (noel_valid, ptr);
+ ptr = utf8_prev_char (noel_valid, ptr);
+ STRCMP_EQUAL("noël", ptr);
+ POINTERS_EQUAL(noel_valid, ptr);
+
+ /* add offset */
+ ptr = utf8_add_offset (noel_valid, 0);
+ STRCMP_EQUAL(noel_valid, ptr);
+ ptr = utf8_add_offset (noel_valid, 1);
+ STRCMP_EQUAL("oël", ptr);
+ ptr = utf8_add_offset (noel_valid, 3);
+ STRCMP_EQUAL("l", ptr);
+
+ /* real position */
+ LONGS_EQUAL(0, utf8_real_pos (noel_valid, 0));
+ LONGS_EQUAL(1, utf8_real_pos (noel_valid, 1));
+ LONGS_EQUAL(2, utf8_real_pos (noel_valid, 2));
+ LONGS_EQUAL(4, utf8_real_pos (noel_valid, 3));
+
+ /* position */
+ LONGS_EQUAL(0, utf8_pos (noel_valid, 0));
+ LONGS_EQUAL(1, utf8_pos (noel_valid, 1));
+ LONGS_EQUAL(2, utf8_pos (noel_valid, 2));
+ LONGS_EQUAL(3, utf8_pos (noel_valid, 4));
+}
+
+/*
+ * Tests functions:
+ * utf8_char_int
+ * utf8_int_string
+ * utf8_wide_char
+ */
+
+TEST(Utf8, Convert)
+{
+ char result[5];
+
+ /* get UTF-8 char as integer */
+ BYTES_EQUAL(0, utf8_char_int (NULL));
+ BYTES_EQUAL(0, utf8_char_int (""));
+ BYTES_EQUAL(65, utf8_char_int ("ABC"));
+ BYTES_EQUAL(235, utf8_char_int ("ë"));
+ BYTES_EQUAL(0x20ac, utf8_char_int ("€"));
+ BYTES_EQUAL(0x24b62, utf8_char_int (han_char));
+
+ BYTES_EQUAL(0x0, utf8_char_int ("\xc0\x80")); /* invalid */
+ BYTES_EQUAL(0x7f, utf8_char_int ("\xc1\xbf")); /* invalid */
+ BYTES_EQUAL(0x80, utf8_char_int ("\xc2\x80"));
+ BYTES_EQUAL(0x7ff, utf8_char_int ("\xdf\xbf"));
+
+ BYTES_EQUAL(0x0, utf8_char_int ("\xe0\x80\x80")); /* invalid */
+ BYTES_EQUAL(0x7ff, utf8_char_int ("\xe0\x9f\xbf")); /* invalid */
+ BYTES_EQUAL(0x800, utf8_char_int ("\xe0\xa0\x80"));
+ BYTES_EQUAL(0xffff, utf8_char_int ("\xef\xbf\xbf"));
+
+ BYTES_EQUAL(0x0, utf8_char_int ("\xf0\x80\x80\x80")); /* invalid */
+ BYTES_EQUAL(0xffff, utf8_char_int ("\xf0\x8f\xbf\xbf")); /* invalid */
+ BYTES_EQUAL(0x10000, utf8_char_int ("\xf0\x90\x80\x80"));
+ BYTES_EQUAL(0x1fffff, utf8_char_int ("\xf7\xbf\xbf\xbf"));
+
+ /* convert unicode char to a string */
+ utf8_int_string (0, NULL);
+ utf8_int_string (0, result);
+ STRCMP_EQUAL("", result);
+ utf8_int_string (235, result);
+ STRCMP_EQUAL("ë", result);
+ utf8_int_string (0x20ac, result);
+ STRCMP_EQUAL("€", result);
+ utf8_int_string (0x24b62, result);
+ STRCMP_EQUAL(han_char, result);
+
+ /* get wide char */
+ BYTES_EQUAL(WEOF, utf8_wide_char (NULL));
+ BYTES_EQUAL(WEOF, utf8_wide_char (""));
+ BYTES_EQUAL(65, utf8_wide_char ("A"));
+ BYTES_EQUAL(0xc3ab, utf8_wide_char ("ë"));
+ BYTES_EQUAL(0xe282ac, utf8_wide_char ("€"));
+ BYTES_EQUAL(0xf0a4ada2, utf8_wide_char (han_char));
+}
+
+/*
+ * Tests functions:
+ * utf8_char_size
+ * utf8_char_size_screen
+ * utf8_strlen
+ * utf8_strnlen
+ * utf8_strlen_screen
+ */
+
+TEST(Utf8, Size)
+{
+ /* char size */
+ LONGS_EQUAL(0, utf8_char_size (NULL));
+ LONGS_EQUAL(1, utf8_char_size (""));
+ LONGS_EQUAL(1, utf8_char_size ("A"));
+ LONGS_EQUAL(2, utf8_char_size ("ë"));
+ LONGS_EQUAL(3, utf8_char_size ("€"));
+ LONGS_EQUAL(4, utf8_char_size (han_char));
+
+ /* char size on screen */
+ LONGS_EQUAL(0, utf8_char_size_screen (NULL));
+ LONGS_EQUAL(0, utf8_char_size_screen (""));
+ LONGS_EQUAL(1, utf8_char_size_screen ("A"));
+ LONGS_EQUAL(1, utf8_char_size_screen ("ë"));
+ LONGS_EQUAL(1, utf8_char_size_screen ("€"));
+ LONGS_EQUAL(1, utf8_char_size_screen (han_char));
+
+ /* length of string (in chars) */
+ LONGS_EQUAL(0, utf8_strlen (NULL));
+ LONGS_EQUAL(0, utf8_strlen (""));
+ LONGS_EQUAL(1, utf8_strlen ("A"));
+ LONGS_EQUAL(1, utf8_strlen ("ë"));
+ LONGS_EQUAL(1, utf8_strlen ("€"));
+ LONGS_EQUAL(1, utf8_strlen (han_char));
+
+ /* length of string (in chars, for max N bytes) */
+ LONGS_EQUAL(0, utf8_strnlen (NULL, 0));
+ LONGS_EQUAL(0, utf8_strnlen ("", 0));
+ LONGS_EQUAL(1, utf8_strnlen ("AZ", 1));
+ LONGS_EQUAL(1, utf8_strnlen ("ëZ", 2));
+ LONGS_EQUAL(1, utf8_strnlen ("€Z", 3));
+ LONGS_EQUAL(1, utf8_strnlen (han_char_z, 4));
+
+ /* length of string on screen (in chars) */
+ LONGS_EQUAL(0, utf8_strlen_screen (NULL));
+ LONGS_EQUAL(0, utf8_strlen_screen (""));
+ LONGS_EQUAL(1, utf8_strlen_screen ("A"));
+ LONGS_EQUAL(1, utf8_strlen_screen ("ë"));
+ LONGS_EQUAL(1, utf8_strlen_screen ("€"));
+ LONGS_EQUAL(1, utf8_strlen_screen (han_char));
+ LONGS_EQUAL(1, utf8_strlen_screen ("\x7f"));
+}
+
+/*
+ * Tests functions:
+ * utf8_charcmp
+ * utf8_charcasecmp
+ * utf8_charcasecmp_range
+ */
+
+TEST(Utf8, Comparison)
+{
+ /* case-sensitive comparison */
+ LONGS_EQUAL(0, utf8_charcmp (NULL, NULL));
+ LONGS_EQUAL(-1, utf8_charcmp (NULL, "abc"));
+ LONGS_EQUAL(1, utf8_charcmp ("abc", NULL));
+ LONGS_EQUAL(0, utf8_charcmp ("axx", "azz"));
+ LONGS_EQUAL(-1, utf8_charcmp ("A", "Z"));
+ LONGS_EQUAL(1, utf8_charcmp ("Z", "A"));
+ LONGS_EQUAL(-1, utf8_charcmp ("A", "a"));
+ LONGS_EQUAL(-1, utf8_charcmp ("ë", "€"));
+
+ /* case-insensitive comparison */
+ LONGS_EQUAL(0, utf8_charcasecmp (NULL, NULL));
+ LONGS_EQUAL(-1, utf8_charcasecmp (NULL, "abc"));
+ LONGS_EQUAL(1, utf8_charcasecmp ("abc", NULL));
+ LONGS_EQUAL(0, utf8_charcasecmp ("axx", "azz"));
+ LONGS_EQUAL(-1, utf8_charcasecmp ("A", "Z"));
+ LONGS_EQUAL(1, utf8_charcasecmp ("Z", "A"));
+ LONGS_EQUAL(0, utf8_charcasecmp ("A", "a"));
+ LONGS_EQUAL(-1, utf8_charcasecmp ("ë", "€"));
+
+ /* case-insensitive comparison with a range */
+ LONGS_EQUAL(0, utf8_charcasecmp_range (NULL, NULL, 30));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range (NULL, "abc", 30));
+ LONGS_EQUAL(1, utf8_charcasecmp_range ("abc", NULL, 30));
+ LONGS_EQUAL(0, utf8_charcasecmp_range ("axx", "azz", 30));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range ("A", "Z", 30));
+ LONGS_EQUAL(1, utf8_charcasecmp_range ("Z", "A", 30));
+ LONGS_EQUAL(0, utf8_charcasecmp_range ("A", "a", 30));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range ("ë", "€", 30));
+ LONGS_EQUAL(0, utf8_charcasecmp_range ("[", "{", 30));
+ LONGS_EQUAL(0, utf8_charcasecmp_range ("]", "}", 30));
+ LONGS_EQUAL(0, utf8_charcasecmp_range ("\\", "|", 30));
+ LONGS_EQUAL(0, utf8_charcasecmp_range ("^", "~", 30));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range ("[", "{", 26));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range ("]", "}", 26));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range ("\\", "|", 26));
+ LONGS_EQUAL(-1, utf8_charcasecmp_range ("^", "~", 26));
+}
+
+/*
+ * Tests functions:
+ * utf8_strndup
+ */
+
+TEST(Utf8, Duplicate)
+{
+ char *str;
+
+ WEE_CHECK_STRNDUP("", noel_valid, 0);
+ WEE_CHECK_STRNDUP("n", noel_valid, 1);
+ WEE_CHECK_STRNDUP("no", noel_valid, 2);
+ WEE_CHECK_STRNDUP("noë", noel_valid, 3);
+ WEE_CHECK_STRNDUP("noël", noel_valid, 4);
+ WEE_CHECK_STRNDUP("noël", noel_valid, 5);
+}
diff --git a/tests/unit/core/test-util.cpp b/tests/unit/core/test-util.cpp
new file mode 100644
index 000000000..96a930e0c
--- /dev/null
+++ b/tests/unit/core/test-util.cpp
@@ -0,0 +1,168 @@
+/*
+ * test-util.cpp - test util functions
+ *
+ * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include "../src/core/wee-util.h"
+}
+
+TEST_GROUP(Util)
+{
+};
+
+/*
+ * Tests functions:
+ * util_timeval_cmp
+ * util_timeval_diff
+ * util_timeval_add
+ */
+
+TEST(Util, Timeval)
+{
+ struct timeval tv1 = { 123456, 12000 };
+ struct timeval tv2 = { 123456, 15000 };
+ struct timeval tv3 = { 123457, 15000 };
+ struct timeval tv;
+
+ /* comparison */
+ LONGS_EQUAL(0, util_timeval_cmp (NULL, NULL));
+ LONGS_EQUAL(-1, util_timeval_cmp (NULL, &tv1));
+ LONGS_EQUAL(1, util_timeval_cmp (&tv1, NULL));
+ LONGS_EQUAL(0, util_timeval_cmp (&tv1, &tv1));
+ LONGS_EQUAL(-1, util_timeval_cmp (&tv1, &tv2));
+ LONGS_EQUAL(1, util_timeval_cmp (&tv2, &tv1));
+
+ /* difference */
+ LONGS_EQUAL(0, util_timeval_diff (NULL, NULL));
+ LONGS_EQUAL(0, util_timeval_diff (NULL, &tv1));
+ LONGS_EQUAL(0, util_timeval_diff (&tv1, NULL));
+ LONGS_EQUAL(3, util_timeval_diff (&tv1, &tv2));
+ LONGS_EQUAL(1003, util_timeval_diff (&tv1, &tv3));
+
+ /* add interval */
+ util_timeval_add (NULL, 0);
+ tv.tv_sec = 123456;
+ tv.tv_usec = 12000;
+ util_timeval_add (&tv, 10);
+ LONGS_EQUAL(123456, tv.tv_sec);
+ LONGS_EQUAL(22000, tv.tv_usec);
+ util_timeval_add (&tv, 4000);
+ LONGS_EQUAL(123460, tv.tv_sec);
+ LONGS_EQUAL(22000, tv.tv_usec);
+}
+
+/*
+ * Tests functions:
+ * util_get_time_string
+ */
+
+TEST(Util, GetTimeString)
+{
+ time_t date;
+ const char *str_date;
+
+ date = 946684800; /* 2000-01-01 00:00 */
+ str_date = util_get_time_string (&date);
+ STRCMP_EQUAL("Sat, 01 Jan 2000 00:00:00", str_date);
+}
+
+/*
+ * Tests functions:
+ * util_signal_search
+ * util_catch_signal
+ */
+
+TEST(Util, Signal)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * util_mkdir_home
+ * util_mkdir
+ * util_mkdir_parents
+ */
+
+TEST(Util, Mkdir)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * util_exec_on_files
+ */
+
+TEST(Util, ExecOnFiles)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * util_search_full_lib_name
+ */
+
+TEST(Util, LibName)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * util_file_get_content
+ */
+
+TEST(Util, FileGetContent)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * util_version_number
+ */
+
+TEST(Util, VersionNumber)
+{
+ BYTES_EQUAL(0x00030200, util_version_number ("0.3.2-dev"));
+ BYTES_EQUAL(0x00030200, util_version_number ("0.3.2-rc1"));
+ BYTES_EQUAL(0x00030200, util_version_number ("0.3.2"));
+ BYTES_EQUAL(0x00030101, util_version_number ("0.3.1.1"));
+ BYTES_EQUAL(0x00030100, util_version_number ("0.3.1"));
+ BYTES_EQUAL(0x00030000, util_version_number ("0.3.0"));
+ BYTES_EQUAL(0x01000000, util_version_number ("1.0"));
+ BYTES_EQUAL(0x01000000, util_version_number ("1.0.0"));
+ BYTES_EQUAL(0x01000000, util_version_number ("1.0.0.0"));
+ BYTES_EQUAL(0x01000100, util_version_number ("1.0.1"));
+ BYTES_EQUAL(0x01000200, util_version_number ("1.0.2"));
+ BYTES_EQUAL(0x01010000, util_version_number ("1.1"));
+ BYTES_EQUAL(0x01010100, util_version_number ("1.1.1"));
+ BYTES_EQUAL(0x01010200, util_version_number ("1.1.2"));
+ BYTES_EQUAL(0x01020304, util_version_number ("1.2.3.4"));
+}