summaryrefslogtreecommitdiff
path: root/tests/test_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_string.c')
-rw-r--r--tests/test_string.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/tests/test_string.c b/tests/test_string.c
new file mode 100644
index 0000000..ef0e2a9
--- /dev/null
+++ b/tests/test_string.c
@@ -0,0 +1,126 @@
+
+#undef NDEBUG /* ensure tests always assert. */
+#include "upb_string.h"
+
+char static_str[] = "Static string.";
+upb_string static_upbstr = UPB_STATIC_STRING(static_str);
+
+static void test_static() {
+ // Static string is initialized appropriately.
+ assert(upb_streql(&static_upbstr, UPB_STRLIT("Static string.")));
+
+ // Taking a ref on a static string returns the same string, and repeated
+ // refs don't get the string in a confused state.
+ assert(upb_string_getref(&static_upbstr) == &static_upbstr);
+ assert(upb_string_getref(&static_upbstr) == &static_upbstr);
+ assert(upb_string_getref(&static_upbstr) == &static_upbstr);
+
+ // Unreffing a static string does nothing (is not harmful).
+ upb_string_unref(&static_upbstr);
+ upb_string_unref(&static_upbstr);
+ upb_string_unref(&static_upbstr);
+ upb_string_unref(&static_upbstr);
+ upb_string_unref(&static_upbstr);
+
+ // Recycling a static string returns a new string (that can be modified).
+ upb_string *str = &static_upbstr;
+ upb_string_recycle(&str);
+ assert(str != &static_upbstr);
+
+ upb_string_unref(str);
+}
+
+static void test_dynamic() {
+ upb_string *str = upb_string_new();
+ assert(str != NULL);
+ upb_string_unref(str);
+
+ // Can also create a string by recycle(NULL).
+ str = NULL;
+ upb_string_recycle(&str);
+ assert(str != NULL);
+
+ // Take a ref and recycle; should create a new string and release a ref
+ // on the old one.
+ upb_string *strcp = upb_string_getref(str);
+ assert(strcp == str);
+ assert(upb_atomic_read(&str->refcount) == 2);
+ upb_string_recycle(&str);
+ assert(strcp != str);
+ assert(upb_atomic_read(&str->refcount) == 1);
+ assert(upb_atomic_read(&strcp->refcount) == 1);
+ upb_string_unref(strcp);
+
+ upb_strcpyc(str, static_str);
+ assert(upb_string_len(str) == (sizeof(static_str) - 1));
+ const char *robuf = upb_string_getrobuf(str);
+ assert(robuf != NULL);
+ assert(upb_streqlc(str, static_str));
+ upb_string_endread(str);
+
+ upb_string *str2 = str;
+ upb_string_recycle(&str2);
+ // No other referents, so should return the same string.
+ assert(str2 == str);
+
+ // Write a shorter string, the same memory should be reused.
+ upb_strcpyc(str, "XX");
+ const char *robuf2 = upb_string_getrobuf(str);
+ assert(robuf2 == robuf);
+ assert(upb_streqlc(str, "XX"));
+ assert(upb_streql(str, UPB_STRLIT("XX")));
+
+ // Make string alias part of another string.
+ str2 = upb_strdupc("WXYZ");
+ upb_string_recycle(&str);
+ upb_string_substr(str, str2, 1, 2);
+ assert(upb_string_len(str) == 2);
+ assert(upb_string_len(str2) == 4);
+ // The two string should be aliasing the same data.
+ const char *robuf3 = upb_string_getrobuf(str);
+ const char *robuf4 = upb_string_getrobuf(str2);
+ assert(robuf3 == robuf4 + 1);
+ // The aliased string should have an extra ref.
+ assert(upb_atomic_read(&str2->refcount) == 2);
+
+ // Recycling str should eliminate the extra ref.
+ upb_string_recycle(&str);
+ assert(upb_atomic_read(&str2->refcount) == 1);
+
+ // Resetting str should reuse its old data.
+ upb_strcpyc(str, "XX");
+ const char *robuf5 = upb_string_getrobuf(str);
+ assert(robuf5 == robuf);
+
+ // Resetting str to something very long should require new data to be
+ // allocated.
+ upb_string_recycle(&str);
+ const char longstring[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+ upb_strcpyc(str, longstring);
+ const char *robuf6 = upb_string_getrobuf(str);
+ assert(robuf6 != robuf);
+ assert(upb_streqlc(str, longstring));
+
+ // Test printf.
+ upb_string_recycle(&str);
+ upb_string_printf(str, "Number: %d, String: %s", 5, "YO!");
+ assert(upb_streqlc(str, "Number: 5, String: YO!"));
+
+ // Test asprintf
+ upb_string *str3 = upb_string_asprintf("Yo %s: " UPB_STRFMT "\n",
+ "Josh", UPB_STRARG(str));
+ const char expected[] = "Yo Josh: Number: 5, String: YO!\n";
+ assert(upb_streqlc(str3, expected));
+
+ upb_string_unref(str);
+ upb_string_unref(str2);
+ upb_string_unref(str3);
+
+ // Unref of NULL is harmless.
+ upb_string_unref(NULL);
+}
+
+int main() {
+ test_static();
+ test_dynamic();
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback