chiark / gitweb /
build fixes
[disorder] / lib / test.c
index 69dbf012aac0af71e98762909945fc2107019d90..781a1fc5fe7fe34859b7782447d8eff0048746ba 100644 (file)
@@ -30,6 +30,9 @@
 #include <assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
 
 #include "utf8.h"
 #include "mem.h"
 #include "inputline.h"
 #include "wstat.h"
 #include "signame.h"
+#include "cache.h"
+#include "filepart.h"
+#include "hash.h"
+#include "selection.h"
+#include "syscalls.h"
+#include "kvp.h"
 
 static int tests, errors;
 static int fail_first;
@@ -95,20 +104,36 @@ static const char *format_utf32(const uint32_t *s) {
   return d.vec;
 }
 
-#define check_string(GOT, WANT) do {                           \
-  const char *g = GOT;                                         \
-  const char *w = WANT;                                                \
-                                                               \
-  if(w == 0) {                                                 \
-    fprintf(stderr, "%s:%d: %s returned 0\n",                  \
-            __FILE__, __LINE__, #GOT);                         \
-    count_error();                                                     \
-  } else if(strcmp(w, g)) {                                    \
-    fprintf(stderr, "%s:%d: %s returned:\n%s\nexpected:\n%s\n",        \
-           __FILE__, __LINE__, #GOT, format(g), format(w));    \
-    count_error();                                                     \
-  }                                                            \
-  ++tests;                                                     \
+#define check_string(GOT, WANT) do {                                    \
+  const char *got = GOT;                                                \
+  const char *want = WANT;                                              \
+                                                                        \
+  if(want == 0) {                                                       \
+    fprintf(stderr, "%s:%d: %s returned 0\n",                           \
+            __FILE__, __LINE__, #GOT);                                  \
+    count_error();                                                      \
+  } else if(strcmp(want, got)) {                                        \
+    fprintf(stderr, "%s:%d: %s returned:\n%s\nexpected:\n%s\n",         \
+           __FILE__, __LINE__, #GOT, format(got), format(want));       \
+    count_error();                                                      \
+  }                                                                     \
+  ++tests;                                                              \
+ } while(0)
+
+#define check_string_prefix(GOT, WANT) do {                             \
+  const char *got = GOT;                                                \
+  const char *want = WANT;                                              \
+                                                                        \
+  if(want == 0) {                                                       \
+    fprintf(stderr, "%s:%d: %s returned 0\n",                           \
+            __FILE__, __LINE__, #GOT);                                  \
+    count_error();                                                      \
+  } else if(strncmp(want, got, strlen(want))) {                         \
+    fprintf(stderr, "%s:%d: %s returned:\n%s\nexpected:\n%s...\n",      \
+           __FILE__, __LINE__, #GOT, format(got), format(want));       \
+    count_error();                                                      \
+  }                                                                     \
+  ++tests;                                                              \
  } while(0)
 
 static uint32_t *ucs4parse(const char *s) {
@@ -215,6 +240,7 @@ static void test_utf8(void) {
   U8("\xF4\x80\x80\x80", "0x100000");
   U8("\xF4\x8F\xBF\xBF", "0x10FFFF");
   insist(!validutf8("\xF4\x90\x80\x80"));
+  insist(!validutf8("\xF4\x80\xFF\x80"));
 
   /* miscellaneous non-UTF-8 rubbish */
   insist(!validutf8("\x80"));
@@ -672,6 +698,8 @@ static void test_unicode(void) {
   fclose(fp);
   breaktest("auxiliary/GraphemeBreakTest.txt", utf32_is_grapheme_boundary);
   breaktest("auxiliary/WordBreakTest.txt", utf32_is_word_boundary);
+  insist(utf32_combining_class(0x40000) == 0);
+  insist(utf32_combining_class(0xE0000) == 0);
 }
 
 static void test_signame(void) {
@@ -684,6 +712,135 @@ static void test_signame(void) {
   insist(find_signal("SIGYOURMUM") == -1);
 }
 
+static void test_cache(void) {
+  const struct cache_type t1 = { 1 }, t2 = { 10 };
+  const char v11[] = "spong", v12[] = "wibble", v2[] = "blat";
+  fprintf(stderr, "test_cache\n");
+  cache_put(&t1, "1_1", v11);
+  cache_put(&t1, "1_2", v12);
+  cache_put(&t2, "2", v2);
+  insist(cache_count() == 3);
+  insist(cache_get(&t2, "2") == v2);
+  insist(cache_get(&t1, "1_1") == v11);
+  insist(cache_get(&t1, "1_2") == v12);
+  insist(cache_get(&t1, "2") == 0);
+  insist(cache_get(&t2, "1_1") == 0);
+  insist(cache_get(&t2, "1_2") == 0);
+  insist(cache_get(&t1, "2") == 0);
+  insist(cache_get(&t2, "1_1") == 0);
+  insist(cache_get(&t2, "1_2") == 0);
+  sleep(2);
+  cache_expire();
+  insist(cache_count() == 1);
+  insist(cache_get(&t1, "1_1") == 0);
+  insist(cache_get(&t1, "1_2") == 0);
+  insist(cache_get(&t2, "2") == v2);
+  cache_clean(0);
+  insist(cache_count() == 0);
+  insist(cache_get(&t2, "2") == 0); 
+}
+
+static void test_filepart(void) {
+  fprintf(stderr, "test_filepart\n");
+  check_string(d_dirname("/"), "/");
+  check_string(d_dirname("/spong"), "/");
+  check_string(d_dirname("/foo/bar"), "/foo");
+  check_string(d_dirname("./bar"), ".");
+  check_string(d_dirname("."), ".");
+  check_string(d_dirname(".."), ".");
+  check_string(d_dirname("../blat"), "..");
+  check_string(d_dirname("wibble"), ".");
+  check_string(extension("foo.c"), ".c");
+  check_string(extension(".c"), ".c");
+  check_string(extension("."), ".");
+  check_string(extension("foo"), "");
+  check_string(extension("./foo"), "");
+  check_string(extension("./foo.c"), ".c");
+}
+
+static void test_selection(void) {
+  hash *h;
+  fprintf(stderr, "test_selection\n");
+  insist((h = selection_new()) != 0);
+  selection_set(h, "one", 1);
+  selection_set(h, "two", 1);
+  selection_set(h, "three", 0);
+  selection_set(h, "four", 1);
+  insist(selection_selected(h, "one") == 1);
+  insist(selection_selected(h, "two") == 1);
+  insist(selection_selected(h, "three") == 0);
+  insist(selection_selected(h, "four") == 1);
+  insist(selection_selected(h, "five") == 0);
+  insist(hash_count(h) == 3);
+  selection_flip(h, "one"); 
+  selection_flip(h, "three"); 
+  insist(selection_selected(h, "one") == 0);
+  insist(selection_selected(h, "three") == 1);
+  insist(hash_count(h) == 3);
+  selection_live(h, "one");
+  selection_live(h, "two");
+  selection_live(h, "three");
+  selection_cleanup(h);
+  insist(selection_selected(h, "one") == 0);
+  insist(selection_selected(h, "two") == 1);
+  insist(selection_selected(h, "three") == 1);
+  insist(selection_selected(h, "four") == 0);
+  insist(selection_selected(h, "five") == 0);
+  insist(hash_count(h) == 2);
+  selection_empty(h);
+  insist(selection_selected(h, "one") == 0);
+  insist(selection_selected(h, "two") == 0);
+  insist(selection_selected(h, "three") == 0);
+  insist(selection_selected(h, "four") == 0);
+  insist(selection_selected(h, "five") == 0);
+  insist(hash_count(h) == 0);
+}
+
+static void test_wstat(void) {
+  pid_t pid;
+  int w;
+  
+  fprintf(stderr, "test_wstat\n");
+  if(!(pid = xfork())) {
+    _exit(1);
+  }
+  while(waitpid(pid, &w, 0) < 0 && errno == EINTR)
+    ;
+  check_string(wstat(w), "exited with status 1");
+  if(!(pid = xfork())) {
+    kill(getpid(), SIGTERM);
+    _exit(-1);
+  }
+  while(waitpid(pid, &w, 0) < 0 && errno == EINTR)
+    ;
+  check_string_prefix(wstat(w), "terminated by signal 15");
+}
+
+static void test_kvp(void) {
+  struct kvp *k;
+  
+  fprintf(stderr, "test_kvp\n");
+#define KVP_URLDECODE(S) kvp_urldecode((S), strlen(S))
+  insist(KVP_URLDECODE("=%zz") == 0);
+  insist(KVP_URLDECODE("=%0") == 0);
+  insist(KVP_URLDECODE("=%0z") == 0);
+  insist(KVP_URLDECODE("=%%") == 0);
+  insist(KVP_URLDECODE("==%") == 0);
+  insist(KVP_URLDECODE("wibble") == 0);
+  insist(KVP_URLDECODE("") == 0);
+  insist(KVP_URLDECODE("wibble&") == 0);
+  insist((k = KVP_URLDECODE("one=bl%61t+foo")) != 0);
+  check_string(kvp_get(k, "one"), "blat foo");
+  insist(kvp_get(k, "ONE") == 0);
+  insist(k->next == 0);
+  insist((k = KVP_URLDECODE("wibble=splat&bar=spong")) != 0);
+  check_string(kvp_get(k, "wibble"), "splat");
+  check_string(kvp_get(k, "bar"), "spong");
+  insist(kvp_get(k, "ONE") == 0);
+  insist(k->next->next == 0);
+  /* TODO test encoding too */
+}
+
 int main(void) {
   fail_first = !!getenv("FAIL_FIRST");
   insist('\n' == 0x0A);
@@ -703,6 +860,8 @@ int main(void) {
   /* client.c */
   /* configuration.c */
   /* event.c */
+  /* filepart.c */
+  test_filepart();
   /* fprintf.c */
   /* heap.c */
   test_heap();
@@ -710,6 +869,7 @@ int main(void) {
   test_hex();
   /* inputline.c */
   /* kvp.c */
+  test_kvp();
   /* log.c */
   /* mem.c */
   /* mime.c */
@@ -732,8 +892,13 @@ int main(void) {
   test_casefold();
   test_words();
   /* wstat.c */
+  test_wstat();
   /* signame.c */
   test_signame();
+  /* cache.c */
+  test_cache();
+  /* selection.c */
+  test_selection();
   fprintf(stderr,  "%d errors out of %d tests\n", errors, tests);
   return !!errors;
 }