summaryrefslogtreecommitdiff
path: root/test/string-tests.c
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2004-10-02 18:47:02 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2004-10-02 18:47:02 +0000
commit0294ff3d3282d1b1c5497f00ea25e5e55e6f4338 (patch)
tree978af6f81c7b7715597871b1e89a9ad083907f1a /test/string-tests.c
downloadneon-0294ff3d3282d1b1c5497f00ea25e5e55e6f4338.tar.gz
Import neon 0.24.0 to begin 0.24.x branch.
git-svn-id: http://svn.webdav.org/repos/projects/neon/branches/0.24.x@243 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
Diffstat (limited to 'test/string-tests.c')
-rw-r--r--test/string-tests.c492
1 files changed, 492 insertions, 0 deletions
diff --git a/test/string-tests.c b/test/string-tests.c
new file mode 100644
index 0000000..93c8508
--- /dev/null
+++ b/test/string-tests.c
@@ -0,0 +1,492 @@
+/*
+ String handling tests
+ Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk>
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "config.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h> /* for the ENOENT definitions in str_errors */
+#endif
+
+#include "ne_string.h"
+
+#include "tests.h"
+
+#undef ONCMP
+#define ONCMP(a,b) ONV(strcmp(a, b), \
+ ("result was [%s] not [%s]", a, b))
+
+static int simple(void) {
+ ne_buffer *s = ne_buffer_create();
+ ON(s == NULL);
+ ne_buffer_zappend(s, "abcde");
+ ONCMP(s->data, "abcde");
+ ON(ne_buffer_size(s) != 5);
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+static int buf_concat(void)
+{
+ ne_buffer *s = ne_buffer_create();
+ ON(s == NULL);
+ ne_buffer_concat(s, "a", "b", "c", "d", "e", "f", "g", NULL);
+ ONCMP(s->data, "abcdefg");
+ ON(ne_buffer_size(s) != 7);
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+static int buf_concat2(void)
+{
+#define RES "alphabetagammadeltaepsilonetatheta"
+ ne_buffer *s = ne_buffer_create();
+ ON(s == NULL);
+ ne_buffer_concat(s, "alpha", "beta", "gamma", "delta", "epsilon",
+ "eta", "theta", NULL);
+ ONCMP(s->data, RES);
+ ON(ne_buffer_size(s) != strlen(RES));
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+static int buf_concat3(void)
+{
+ ne_buffer *s = ne_buffer_create();
+ ON(s == NULL);
+ ne_buffer_zappend(s, "foobar");
+ ne_buffer_concat(s, "norman", NULL);
+ ONCMP(s->data, "foobarnorman");
+ ON(ne_buffer_size(s) != 12);
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+static int append(void) {
+ ne_buffer *s = ne_buffer_create();
+ ON(s == NULL);
+ ne_buffer_append(s, "a", 1);
+ ne_buffer_append(s, "b", 1);
+ ne_buffer_append(s, "c", 1);
+ ONCMP(s->data, "abc");
+ ON(ne_buffer_size(s) != 3);
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+static int grow(void)
+{
+ ne_buffer *s = ne_buffer_ncreate(2);
+ ON(s == NULL);
+ ne_buffer_append(s, "a", 1);
+ ne_buffer_grow(s, 4);
+ ONCMP(s->data, "a");
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+static int alter(void) {
+ ne_buffer *s = ne_buffer_create();
+ char *d;
+ ON(s == NULL);
+ ne_buffer_zappend(s, "abcdefg");
+ d = s->data;
+ ON(d == NULL);
+ d[2] = '\0';
+ ne_buffer_altered(s);
+ ONCMP(s->data, "ab");
+ ON(ne_buffer_size(s) != 2);
+ ne_buffer_zappend(s, "hijkl");
+ ONCMP(s->data, "abhijkl");
+ ne_buffer_destroy(s);
+ return OK;
+}
+
+/* Macros for testing ne_token. */
+
+#define TEST(res) do { \
+ char *tok = ne_token(&pnt, ','); \
+ ONN(res ": return", tok == NULL); \
+ ONN(res ": compare", strcmp(tok, (res))); \
+ ONN(res ": modify", pnt == NULL); \
+} while (0)
+
+#define LASTTEST(res) do { \
+ char *tok = ne_token(&pnt, ','); \
+ ONN(res ": last return", tok == NULL); \
+ ONN(res ": last compare", strcmp(tok, (res))); \
+ ONN(res ": last modify", pnt != NULL); \
+} while (0)
+
+#define QTEST(res) do { \
+ char *tok = ne_qtoken(&pnt, ',', QUOTES); \
+ ONN(res ": return", tok == NULL); \
+ ONN(res ": compare", strcmp(tok, (res))); \
+ ONN(res ": modify", pnt == NULL); \
+} while (0)
+
+#define QLASTTEST(res) do { \
+ char *tok = ne_qtoken(&pnt, ',', QUOTES); \
+ ONN(res ": last return", tok == NULL); \
+ ONN(res ": last compare", strcmp(tok, (res))); \
+ ONN(res ": last modify", pnt != NULL); \
+} while (0)
+
+static int token1(void)
+{
+ char *str = ne_strdup("a,b,c,d"), *pnt = str;
+
+ TEST("a"); TEST("b"); TEST("c"); LASTTEST("d");
+
+ ne_free(str);
+ return OK;
+}
+
+static int token2(void)
+{
+ char *str = ne_strdup("norman,fishing, elsewhere"), *pnt = str;
+
+ TEST("norman"); TEST("fishing"); LASTTEST(" elsewhere");
+
+ ne_free(str);
+ return OK;
+}
+
+static int nulls(void)
+{
+ char *str = ne_strdup("alpha,,gamma"), *pnt = str;
+
+ TEST("alpha"); TEST(""); LASTTEST("gamma");
+ ne_free(str);
+
+ pnt = str = ne_strdup(",,,wooo");
+ TEST(""); TEST(""); TEST(""); LASTTEST("wooo");
+ ne_free(str);
+
+ pnt = str = ne_strdup("wooo,,,");
+ TEST("wooo"); TEST(""); TEST(""); LASTTEST("");
+ ne_free(str);
+
+ return OK;
+}
+
+static int empty(void)
+{
+ char *str = ne_strdup(""), *pnt = str;
+
+ LASTTEST("");
+ ne_free(str);
+
+ return OK;
+}
+
+#undef QUOTES
+#define QUOTES "'"
+
+static int quoted(void)
+{
+ char *str =
+ ne_strdup("alpha,'beta, a fish called HELLO!?',sandwiches");
+ char *pnt = str;
+
+ QTEST("alpha");
+ QTEST("'beta, a fish called HELLO!?'");
+ QLASTTEST("sandwiches");
+
+ ne_free(str);
+ return OK;
+}
+
+static int badquotes(void)
+{
+ char *str = ne_strdup("alpha,'blah"), *pnt = str;
+
+ QTEST("alpha");
+ ON(ne_qtoken(&pnt, ',', QUOTES) != NULL);
+
+ ne_free(str);
+ return OK;
+}
+
+/* for testing ne_shave. */
+#undef TEST
+#define TEST(str, ws, res) do { \
+ char *s = ne_strdup((str)); \
+ char *r = ne_shave(s, (ws)); \
+ ONN("[" str "]", strcmp(r, (res))); \
+ ne_free(s); \
+} while (0)
+
+static int shave(void)
+{
+ TEST(" b ", " ", "b");
+ TEST("b", " ", "b");
+ TEST(" b ", " ", "b");
+ TEST("--bbb-----", "-", "bbb");
+ TEST("hello, world ", " ", "hello, world");
+ TEST("<<><<<><<this is foo<<><<<<><<", "<>", "this is foo");
+ TEST("09809812342347I once saw an helicopter0012312312398", "0123456789",
+ "I once saw an helicopter");
+ return OK;
+}
+
+/* Regression test for ne_shave call which should produce an empty
+ * string. */
+static int shave_regress(void)
+{
+ TEST("\"\"", "\"", "");
+ return OK;
+}
+
+/* Test the ne_token/ne_shave combination. */
+
+#undef TEST
+#undef LASTTEST
+
+#define TEST(res) do { \
+ char *tok = ne_token(&pnt, ','); \
+ ONN(res ": return", tok == NULL); \
+ tok = ne_shave(tok, " "); \
+ ONN(res ": shave", tok == NULL); \
+ ONN(res ": compare", strcmp(tok, (res))); \
+ ONN(res ": modify", pnt == NULL); \
+} while (0)
+
+
+#define LASTTEST(res) do { \
+ char *tok = ne_token(&pnt, ','); \
+ ONN(res ": last return", tok == NULL); \
+ tok = ne_shave(tok, " "); \
+ ONN(res ": last shave", tok == NULL); \
+ ONN(res ": last compare", strcmp(tok, (res))); \
+ ONN(res ": last modify", pnt != NULL); \
+} while (0)
+
+/* traditional use of ne_token/ne_shave. */
+static int combo(void)
+{
+ char *str = ne_strdup(" fred , mary, jim , alice, david"), *pnt = str;
+
+ TEST("fred"); TEST("mary"); TEST("jim"); TEST("alice");
+ LASTTEST("david");
+
+ ne_free(str);
+ return 0;
+}
+
+static int concat(void)
+{
+#define CAT(res, args) do { char *str = ne_concat args; \
+ONCMP(str, res); \
+ne_free(str); } while (0)
+ CAT("alphabeta", ("alpha", "beta", NULL));
+ CAT("alpha", ("alpha", "", "", NULL));
+ CAT("", ("", NULL));
+ CAT("", ("", "", "", NULL));
+ CAT("alpha", ("", "a", "lph", "", "a", NULL));
+ return OK;
+}
+
+static int str_errors(void)
+{
+ char expect[200], actual[200];
+
+ strncpy(expect, strerror(ENOENT), sizeof(expect));
+ ONN("ne_strerror did not return passed-in buffer",
+ ne_strerror(ENOENT, actual, sizeof(actual)) != actual);
+
+ ONV(strcmp(expect, actual),
+ ("error from ENOENT was `%s' not `%s'", actual, expect));
+
+ /* Test truncated error string is still NUL-terminated. */
+ ne_strerror(ENOENT, actual, 6);
+ ONN("truncated string had wrong length", strlen(actual) != 5);
+
+ return OK;
+}
+
+static int strnzcpy(void)
+{
+ char buf[5];
+
+ ne_strnzcpy(buf, "abcdefghi", sizeof buf);
+ ONV(strcmp(buf, "abcd"), ("result was `%s' not `abcd'", buf));
+
+ ne_strnzcpy(buf, "ab", sizeof buf);
+ ONV(strcmp(buf, "ab"), ("result was `%s' not `ab'", buf));
+
+ return OK;
+}
+
+#define FOX_STRING "The quick brown fox jumped over the lazy dog"
+#define PUNC_STRING "<>,.;'#:@~[]{}!\"$%^&*()_+-="
+
+static int cleaner(void)
+{
+ static const char *strings[] = {
+ "alpha", "alpha",
+ "pretty\033[41mcolours", "pretty [41mcolours",
+ "beta\n", "beta ",
+ "del\rt\na", "del t a",
+ FOX_STRING, FOX_STRING,
+ "0123456789", "0123456789",
+ PUNC_STRING, PUNC_STRING,
+ "\01blah blee\05bloo", " blah blee bloo",
+ NULL,
+ };
+ unsigned int n;
+
+ for (n = 0; strings[n]; n+=2) {
+ char *act = ne_strclean(ne_strdup(strings[n]));
+
+ ONV(strcmp(act, strings[n+1]),
+ ("cleansed to `%s' not `%s'", act, strings[n+1]));
+
+ ne_free(act);
+ }
+
+ return OK;
+}
+
+/* Check that raw data 'raw', of length 'len', has base64 encoding
+ * of 'expected'. */
+static int b64_check(const unsigned char *raw, size_t len,
+ const char *expected)
+{
+ char *encoded = ne_base64(raw, len);
+ unsigned char *decoded;
+ size_t dlen;
+
+ ONV(strcmp(encoded, expected),
+ ("base64(\"%s\") gave \"%s\" not \"%s\"", raw, encoded, expected));
+
+ dlen = ne_unbase64(encoded, &decoded);
+ ONV(dlen != len,
+ ("decoded `%s' length was %" NE_FMT_SIZE_T " not %" NE_FMT_SIZE_T,
+ expected, dlen, len));
+
+ ONV(memcmp(raw, decoded, dlen),
+ ("decoded `%s' as `%.*s' not `%.*s'",
+ expected, dlen, decoded, dlen, raw));
+
+ ne_free(decoded);
+ ne_free(encoded);
+ return OK;
+}
+
+/* ALLBITS: base64 encoding of "\0..\377" */
+#define ALLBITS \
+"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss" \
+"LS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ" \
+"WltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWG" \
+"h4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz" \
+"tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g" \
+"4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
+
+static int base64(void)
+{
+ unsigned char bits[256];
+ size_t n;
+
+#define B64B(x, l, y) CALL(b64_check(x, l, y))
+#define B64(x, y) B64B(x, strlen(x), y)
+
+ /* invent these with
+ * $ printf "string" | uuencode -m blah
+ */
+ B64("a", "YQ==");
+ B64("bb", "YmI=");
+ B64("ccc", "Y2Nj");
+ B64("Hello, world", "SGVsbG8sIHdvcmxk");
+ B64("Aladdin:open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
+ B64("I once saw a dog called norman.\n",
+ "SSBvbmNlIHNhdyBhIGRvZyBjYWxsZWQgbm9ybWFuLgo=");
+ B64("The quick brown fox jumped over the lazy dog",
+ "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c=");
+
+ /* binary data..
+ * $ printf "string" | wc -c # get the length
+ * $ printf "string" | uuencode -m blah # get the base64
+ */
+ B64B("\0\0\0\0\0\n", 6, "AAAAAAAK");
+ B64B("I once wished \0 upon a \0 fish.", 30,
+ "SSBvbmNlIHdpc2hlZCAAIHVwb24gYSAAIGZpc2gu");
+ B64B("\201\202\203\204", 4, "gYKDhA==");
+
+ for (n = 0; n < sizeof bits; n++)
+ bits[n] = (unsigned char)n;
+ CALL(b64_check(bits, sizeof bits, ALLBITS));
+
+#undef B64
+#undef B64B
+ return OK;
+}
+
+static int unbase64(void)
+{
+ static const char *ts[] = {
+ "", "a", "ab", "abc",
+ "}bcd", "a}cd", "ab}d", "abc}", " ",
+ "^bcd", "a^cd", "ab^d", "abc^",
+ "====", "=bcd", "a=cd", "ab=d", "a==d", "a=c=",
+ NULL
+ };
+ size_t n;
+
+ for (n = 0; ts[n]; n++) {
+ unsigned char *tmp;
+ ONV(ne_unbase64(ts[n], &tmp) != 0,
+ ("invalid string `%s' was decoded", ts[n]));
+ }
+
+ return OK;
+}
+
+ne_test tests[] = {
+ T(simple),
+ T(buf_concat),
+ T(buf_concat2),
+ T(buf_concat3),
+ T(append),
+ T(grow),
+ T(alter),
+ T(token1),
+ T(token2),
+ T(nulls),
+ T(empty),
+ T(quoted),
+ T(badquotes),
+ T(shave),
+ T(shave_regress),
+ T(combo),
+ T(concat),
+ T(str_errors),
+ T(strnzcpy),
+ T(cleaner),
+ T(base64),
+ T(unbase64),
+ T(NULL)
+};
+