summaryrefslogtreecommitdiff
path: root/tests/unit/bson
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/bson')
-rw-r--r--tests/unit/bson/bson_append_array.c65
-rw-r--r--tests/unit/bson/bson_append_binary.c56
-rw-r--r--tests/unit/bson/bson_append_boolean.c43
-rw-r--r--tests/unit/bson/bson_append_document.c67
-rw-r--r--tests/unit/bson/bson_append_double.c41
-rw-r--r--tests/unit/bson/bson_append_int32.c40
-rw-r--r--tests/unit/bson/bson_append_int64.c41
-rw-r--r--tests/unit/bson/bson_append_js_code.c66
-rw-r--r--tests/unit/bson/bson_append_js_code_w_scope.c79
-rw-r--r--tests/unit/bson/bson_append_null.c40
-rw-r--r--tests/unit/bson/bson_append_oid.c43
-rw-r--r--tests/unit/bson/bson_append_regexp.c45
-rw-r--r--tests/unit/bson/bson_append_string.c61
-rw-r--r--tests/unit/bson/bson_append_symbol.c61
-rw-r--r--tests/unit/bson/bson_append_timestamp.c41
-rw-r--r--tests/unit/bson/bson_append_utc_datetime.c41
-rw-r--r--tests/unit/bson/bson_build.c70
-rw-r--r--tests/unit/bson/bson_build_full.c71
-rw-r--r--tests/unit/bson/bson_cursor_find.c39
-rw-r--r--tests/unit/bson/bson_cursor_find_next.c33
-rw-r--r--tests/unit/bson/bson_cursor_get_array.c44
-rw-r--r--tests/unit/bson/bson_cursor_get_binary.c60
-rw-r--r--tests/unit/bson/bson_cursor_get_boolean.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_document.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_double.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_int32.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_int64.c45
-rw-r--r--tests/unit/bson/bson_cursor_get_javascript.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_javascript_w_scope.c57
-rw-r--r--tests/unit/bson/bson_cursor_get_oid.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_regex.c52
-rw-r--r--tests/unit/bson/bson_cursor_get_string.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_symbol.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_timestamp.c43
-rw-r--r--tests/unit/bson/bson_cursor_get_utc_datetime.c43
-rw-r--r--tests/unit/bson/bson_cursor_key.c30
-rw-r--r--tests/unit/bson/bson_cursor_new.c28
-rw-r--r--tests/unit/bson/bson_cursor_next.c42
-rw-r--r--tests/unit/bson/bson_cursor_type.c30
-rw-r--r--tests/unit/bson/bson_cursor_type_as_string.c31
-rw-r--r--tests/unit/bson/bson_empty.c22
-rw-r--r--tests/unit/bson/bson_find.c34
-rw-r--r--tests/unit/bson/bson_new.c28
-rw-r--r--tests/unit/bson/bson_new_from_data.c46
-rw-r--r--tests/unit/bson/bson_reset.c27
-rw-r--r--tests/unit/bson/bson_type_as_string.c40
-rw-r--r--tests/unit/bson/bson_validate_key.c36
47 files changed, 2125 insertions, 0 deletions
diff --git a/tests/unit/bson/bson_append_array.c b/tests/unit/bson/bson_append_array.c
new file mode 100644
index 0000000..040f0ed
--- /dev/null
+++ b/tests/unit/bson/bson_append_array.c
@@ -0,0 +1,65 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_array (void)
+{
+ bson *b, *e1, *e2;
+
+ e1 = bson_new ();
+ bson_append_int32 (e1, "0", 1984);
+ bson_append_string (e1, "1", "hello world", -1);
+ bson_finish (e1);
+
+ e2 = bson_new ();
+ bson_append_string (e2, "0", "bar", -1);
+ ok (bson_append_array (e2, "1", e1),
+ "bson_append_array() works");
+ bson_finish (e2);
+ bson_free (e1);
+
+ b = bson_new ();
+ ok (bson_append_array (b, "0", e2),
+ "bson_append_array() works still");
+ bson_finish (b);
+ bson_free (e2);
+
+ cmp_ok (bson_size (b), "==", 58, "BSON array element size check");
+ ok (memcmp (bson_data (b),
+ "\072\000\000\000\004\060\000\062\000\000\000\002\060\000\004"
+ "\000\000\000\142\141\162\000\004\061\000\037\000\000\000\020"
+ "\060\000\300\007\000\000\002\061\000\014\000\000\000\150\145"
+ "\154\154\157\040\167\157\162\154\144\000\000\000\000",
+ bson_size (b)) == 0,
+ "BSON array element contents check");
+
+ bson_free (b);
+
+ e1 = bson_new ();
+ bson_append_int32 (e1, "0", 1984);
+ b = bson_new ();
+
+ ok (bson_append_array (b, "array", e1) == FALSE,
+ "bson_append_array() with an unfinished array should fail");
+ bson_finish (e1);
+ ok (bson_append_array (b, NULL, e1) == FALSE,
+ "bson_append_array() with a NULL name should fail");
+ ok (bson_append_array (b, "foo", NULL) == FALSE,
+ "bson_append_array() with a NULL array should fail");
+ ok (bson_append_array (NULL, "foo", e1) == FALSE,
+ "bson_append_array() with a NULL BSON should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_array (b, "array", e1) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (e1);
+ bson_free (b);
+}
+
+RUN_TEST (10, bson_array);
diff --git a/tests/unit/bson/bson_append_binary.c b/tests/unit/bson/bson_append_binary.c
new file mode 100644
index 0000000..06ea362
--- /dev/null
+++ b/tests/unit/bson/bson_append_binary.c
@@ -0,0 +1,56 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_binary (void)
+{
+ bson *b;
+
+ b = bson_new ();
+ ok (bson_append_binary (b, "binary0", BSON_BINARY_SUBTYPE_GENERIC,
+ (guint8 *)"foo\0bar", 7),
+ "bson_append_binary(), type 0 works");
+ ok (bson_append_binary (b, "binary2", BSON_BINARY_SUBTYPE_BINARY,
+ (guint8 *)"\0\0\0\7foo\0bar", 11),
+ "bson_append_binary(), type 2 works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 51, "BSON binary element size check");
+ ok (memcmp (bson_data (b),
+ "\063\000\000\000\005\142\151\156\141\162\171\060\000\007\000"
+ "\000\000\000\146\157\157\000\142\141\162\005\142\151\156\141"
+ "\162\171\062\000\013\000\000\000\002\000\000\000\007\146\157"
+ "\157\000\142\141\162\000",
+ bson_size (b)) == 0,
+ "BSON binary element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_binary (b, NULL, BSON_BINARY_SUBTYPE_GENERIC,
+ (guint8 *)"foo\0bar", 7) == FALSE,
+ "bson_append_binary() without a key name should fail");
+ ok (bson_append_binary (b, "binary1", BSON_BINARY_SUBTYPE_GENERIC,
+ NULL, 10) == FALSE,
+ "bson_append_binary () without binary data should fail");
+ ok (bson_append_binary (b, "binary3", BSON_BINARY_SUBTYPE_GENERIC,
+ (guint8 *)"foo\0bar", -1) == FALSE,
+ "bson_append_binary () with an invalid length should fail");
+ ok (bson_append_binary (NULL, "binary1", BSON_BINARY_SUBTYPE_GENERIC,
+ (guint8 *)"foo\0bar", 7) == FALSE,
+ "bson_append_binary () without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_binary (b, "binary", BSON_BINARY_SUBTYPE_GENERIC,
+ (guint8 *)"foo\0bar", 7) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (10, bson_binary);
diff --git a/tests/unit/bson/bson_append_boolean.c b/tests/unit/bson/bson_append_boolean.c
new file mode 100644
index 0000000..03df0a5
--- /dev/null
+++ b/tests/unit/bson/bson_append_boolean.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_boolean (void)
+{
+ bson *b;
+
+ b = bson_new ();
+ ok (bson_append_boolean (b, "FALSE", FALSE),
+ "bson_append_boolean() works");
+ ok (bson_append_boolean (b, "TRUE", TRUE),
+ "bson_append_boolean() works still");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 20, "BSON boolean element size check");
+ ok (memcmp (bson_data (b),
+ "\024\000\000\000\010\106\101\114\123\105\000\000\010\124\122"
+ "\125\105\000\001\000",
+ bson_size (b)) == 0,
+ "BSON boolean element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_boolean (b, NULL, TRUE) == FALSE,
+ "bson_append_boolean() with a NULL key should fail");
+ ok (bson_append_boolean (NULL, "TRUE", TRUE) == FALSE,
+ "bson_append_boolean() without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_boolean (b, "b", TRUE) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (8, bson_boolean);
diff --git a/tests/unit/bson/bson_append_document.c b/tests/unit/bson/bson_append_document.c
new file mode 100644
index 0000000..04d077c
--- /dev/null
+++ b/tests/unit/bson/bson_append_document.c
@@ -0,0 +1,67 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_document (void)
+{
+ bson *b, *e1, *e2;
+
+ e1 = bson_new ();
+ bson_append_int32 (e1, "i32", 1984);
+ bson_append_string (e1, "str", "hello world", -1);
+ bson_finish (e1);
+
+ e2 = bson_new ();
+ bson_append_string (e2, "foo", "bar", -1);
+ ok (bson_append_document (e2, "subd", e1),
+ "bson_append_document() works");
+ bson_finish (e2);
+ bson_free (e1);
+
+ b = bson_new ();
+ ok (bson_append_document (b, "doc", e2),
+ "bson_append_document() works still");
+ bson_finish (b);
+ bson_free (e2);
+
+ cmp_ok (bson_size (b), "==", 69, "BSON document element size check");
+ ok (memcmp (bson_data (b),
+ "\105\000\000\000\003\144\157\143\000\073\000\000\000\002\146"
+ "\157\157\000\004\000\000\000\142\141\162\000\003\163\165\142"
+ "\144\000\043\000\000\000\020\151\063\062\000\300\007\000\000"
+ "\002\163\164\162\000\014\000\000\000\150\145\154\154\157\040"
+ "\167\157\162\154\144\000\000\000\000",
+ bson_size (b)) == 0,
+ "BSON document element contents check");
+
+ bson_free (b);
+
+ e1 = bson_new ();
+ bson_append_int32 (e1, "foo", 42);
+ b = bson_new ();
+
+ ok (bson_append_document (b, "doc", e1) == FALSE,
+ "bson_append_document() with an unfinished document should fail");
+ bson_finish (e1);
+ ok (bson_append_document (b, NULL, e1) == FALSE,
+ "bson_append_document() with a NULL key should fail");
+ ok (bson_append_document (b, "doc", NULL) == FALSE,
+ "bson_append_document() with a NULL document should fail");
+ ok (bson_append_document (NULL, "doc", e1) == FALSE,
+ "bson_append_document() without a BSON object should fail");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_document (b, "doc", e1) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (e1);
+ bson_free (b);
+}
+
+RUN_TEST (10, bson_document);
diff --git a/tests/unit/bson/bson_append_double.c b/tests/unit/bson/bson_append_double.c
new file mode 100644
index 0000000..de62c15
--- /dev/null
+++ b/tests/unit/bson/bson_append_double.c
@@ -0,0 +1,41 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_double (void)
+{
+ bson *b;
+ double d = 3.14;
+
+ b = bson_new ();
+ ok (bson_append_double (b, "double", d), "bson_append_double() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 21, "BSON double element size check");
+ ok (memcmp (bson_data (b),
+ "\025\000\000\000\001\144\157\165\142\154\145\000\037\205\353"
+ "\121\270\036\011\100\000",
+ bson_size (b)) == 0,
+ "BSON double element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_double (b, NULL, d) == FALSE,
+ "bson_append_double() with a NULL key should fail");
+ ok (bson_append_double (NULL, "double", d) == FALSE,
+ "bson_append_double() without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_double (b, "d", d) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_double);
diff --git a/tests/unit/bson/bson_append_int32.c b/tests/unit/bson/bson_append_int32.c
new file mode 100644
index 0000000..e2a2867
--- /dev/null
+++ b/tests/unit/bson/bson_append_int32.c
@@ -0,0 +1,40 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_int32 (void)
+{
+ bson *b;
+ gint32 i = 1984;
+
+ b = bson_new ();
+ ok (bson_append_int32 (b, "i32", i), "bson_append_int32() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 14, "BSON int32 element size check");
+ ok (memcmp (bson_data (b),
+ "\016\000\000\000\020\151\063\062\000\300\007\000\000\000",
+ bson_size (b)) == 0,
+ "BSON int32 element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_int32 (b, NULL, i) == FALSE,
+ "bson_append_int32() with a NULL key should fail");
+ ok (bson_append_int32 (NULL, "i32", i) == FALSE,
+ "bson_append_int32() without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_int32 (b, "i32", i) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_int32);
diff --git a/tests/unit/bson/bson_append_int64.c b/tests/unit/bson/bson_append_int64.c
new file mode 100644
index 0000000..22d9691
--- /dev/null
+++ b/tests/unit/bson/bson_append_int64.c
@@ -0,0 +1,41 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_int64 (void)
+{
+ bson *b;
+ gint64 l = 9876543210;
+
+ b = bson_new ();
+ ok (bson_append_int64 (b, "i64", l), "bson_append_int64() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 18, "BSON int64 element size check");
+ ok (memcmp (bson_data (b),
+ "\022\000\000\000\022\151\066\064\000\352\026\260\114\002\000"
+ "\000\000\000",
+ bson_size (b)) == 0,
+ "BSON int64 element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_int64 (b, NULL, l) == FALSE,
+ "bson_append_int64() with a NULL key should fail");
+ ok (bson_append_int64 (NULL, "i64", l) == FALSE,
+ "bson_append_int64() without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_int64 (b, "i64", l) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_int64);
diff --git a/tests/unit/bson/bson_append_js_code.c b/tests/unit/bson/bson_append_js_code.c
new file mode 100644
index 0000000..4b250b0
--- /dev/null
+++ b/tests/unit/bson/bson_append_js_code.c
@@ -0,0 +1,66 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_js_code (void)
+{
+ bson *b;
+
+ /* Test #1: A single JS element, with default size. */
+ b = bson_new ();
+ ok (bson_append_javascript (b, "hello",
+ "function () { print (\"hello world!\"); }", -1),
+ "bson_append_javascript() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 56, "BSON javascript element size check");
+ ok (memcmp (bson_data (b),
+ "\070\000\000\000\015\150\145\154\154\157\000\050\000\000\000"
+ "\146\165\156\143\164\151\157\156\040\050\051\040\173\040\160"
+ "\162\151\156\164\040\050\042\150\145\154\154\157\040\167\157"
+ "\162\154\144\041\042\051\073\040\175\000\000",
+ bson_size (b)) == 0,
+ "BSON javascript element contents check");
+ bson_free (b);
+
+ /* Test #2: A single javascript element, with explicit length. */
+ b = bson_new ();
+ ok (bson_append_javascript (b, "hello",
+ "print (\"hello world!\"); garbage is gone.",
+ strlen ("print (\"hello world!\");")),
+ "bson_append_javascript() with explicit length works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 40, "BSON javascript element size check, #2");
+ ok (memcmp (bson_data (b),
+ "\050\000\000\000\015\150\145\154\154\157\000\030\000\000\000"
+ "\160\162\151\156\164\040\050\042\150\145\154\154\157\040\167"
+ "\157\162\154\144\041\042\051\073\000\000",
+ bson_size (b)) == 0,
+ "BSON javascript element contents check, #2");
+ bson_free (b);
+
+ /* Test #3: Negative test, passing an invalid arguments. */
+ b = bson_new ();
+ ok (bson_append_javascript (b, "hello", "print();", -42) == FALSE,
+ "bson_append_javascript() with an invalid length should fail");
+ ok (bson_append_javascript (b, NULL, "print();", -1) == FALSE,
+ "bson_append_javascript() should fail without a key name");
+ ok (bson_append_javascript (b, "hello", NULL, -1) == FALSE,
+ "bson_append_javascript() should fail without javascript code");
+ ok (bson_append_javascript (NULL, "hello", "print();", -1) == FALSE,
+ "bson_append_javascript() should fail without a BSON object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_javascript (b, "js", "print();", -1) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (12, bson_js_code);
diff --git a/tests/unit/bson/bson_append_js_code_w_scope.c b/tests/unit/bson/bson_append_js_code_w_scope.c
new file mode 100644
index 0000000..09297f3
--- /dev/null
+++ b/tests/unit/bson/bson_append_js_code_w_scope.c
@@ -0,0 +1,79 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_js_code_w_scope (void)
+{
+ bson *b, *scope;
+
+ scope = bson_new ();
+ bson_append_string (scope, "foo", "bar", -1);
+ bson_finish (scope);
+
+ /* Test #1: A single JS element, with default size. */
+ b = bson_new ();
+ ok (bson_append_javascript_w_scope (b, "f",
+ "alert ('hello');", -1,
+ scope),
+ "bson_append_javascript_w_scope() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 51, "BSON javascript w/ element size check");
+ ok (memcmp (bson_data (b),
+ "\063\000\000\000\017\146\000\053\000\000\000\021\000\000\000"
+ "\141\154\145\162\164\040\050\047\150\145\154\154\157\047\051"
+ "\073\000\022\000\000\000\002\146\157\157\000\004\000\000\000"
+ "\142\141\162\000\000\000",
+ bson_size (b)) == 0,
+ "BSON javascript w/ scope element contents check");
+ bson_free (b);
+
+ /* Test #2: A single javascript element, with explicit length. */
+ b = bson_new ();
+ ok (bson_append_javascript_w_scope (b, "f",
+ "alert ('hello'); garbage",
+ strlen ("alert ('hello');"),
+ scope),
+ "bson_append_javascript_w_scope() with explicit length works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 51, "BSON javascript w/ element size check");
+ ok (memcmp (bson_data (b),
+ "\063\000\000\000\017\146\000\053\000\000\000\021\000\000\000"
+ "\141\154\145\162\164\040\050\047\150\145\154\154\157\047\051"
+ "\073\000\022\000\000\000\002\146\157\157\000\004\000\000\000"
+ "\142\141\162\000\000\000",
+ bson_size (b)) == 0,
+ "BSON javascript w/ scope element contents check");
+ bson_free (b);
+
+ /* Test #3: Negative test, passing an invalid arguments. */
+ b = bson_new ();
+
+ ok (bson_append_javascript_w_scope (b, "hello", "print();",
+ -42, scope) == FALSE,
+ "bson_append_javascript_w_scope() with an invalid length should fail");
+ ok (bson_append_javascript_w_scope (b, NULL, "print();", -1, scope) == FALSE,
+ "bson_append_javascript_w_scope() should fail without a key name");
+ ok (bson_append_javascript_w_scope (b, "hello", NULL, -1, scope) == FALSE,
+ "bson_append_javascript_w_scope() should fail without javascript code");
+ ok (bson_append_javascript_w_scope (NULL, "hello", "print();",
+ -1, scope) == FALSE,
+ "bson_append_javascript_w_scope() should fail without a BSON object");
+ ok (bson_append_javascript_w_scope (b, "hello", "print();",
+ -1, NULL) == FALSE,
+ "bson_append_javascript_w_scope() should fail without a scope object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_javascript_w_scope (b, "js", "print();", -1, scope) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (13, bson_js_code_w_scope);
diff --git a/tests/unit/bson/bson_append_null.c b/tests/unit/bson/bson_append_null.c
new file mode 100644
index 0000000..294ea50
--- /dev/null
+++ b/tests/unit/bson/bson_append_null.c
@@ -0,0 +1,40 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_null (void)
+{
+ bson *b;
+
+ b = bson_new ();
+ ok (bson_append_null (b, "null"),
+ "bson_append_null() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 11, "BSON NULL element size check");
+ ok (memcmp (bson_data (b),
+ "\013\000\000\000\012\156\165\154\154\000\000",
+ bson_size (b)) == 0,
+ "BSON NULL element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_null (b, NULL) == FALSE,
+ "bson_append_null() should fail without a key name");
+ ok (bson_append_null (NULL, "null") == FALSE,
+ "bson_append_null() should fail without a BSON object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_null (b, "null") == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_null);
diff --git a/tests/unit/bson/bson_append_oid.c b/tests/unit/bson/bson_append_oid.c
new file mode 100644
index 0000000..2db75a3
--- /dev/null
+++ b/tests/unit/bson/bson_append_oid.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_oid (void)
+{
+ bson *b;
+ guint8 oid[] = "1234567890ab";
+
+ b = bson_new ();
+ ok (bson_append_oid (b, "_id", oid), "bson_append_oid() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 22, "BSON OID element size check");
+ ok (memcmp (bson_data (b),
+ "\026\000\000\000\007\137\151\144\000\061\062\063\064\065\066"
+ "\067\070\071\060\141\142\000",
+ bson_size (b)) == 0,
+ "BSON OID element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_oid (b, "_id", NULL) == FALSE,
+ "bson_append_oid() should fail without an OID");
+ ok (bson_append_oid (b, NULL, oid) == FALSE,
+ "bson_append_oid() should fail without a key name");
+ ok (bson_append_oid (NULL, "_id", oid) == FALSE,
+ "bson_append_oid() should fail without a BSON object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_oid (b, "_id", oid) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (8, bson_oid);
diff --git a/tests/unit/bson/bson_append_regexp.c b/tests/unit/bson/bson_append_regexp.c
new file mode 100644
index 0000000..172cd2a
--- /dev/null
+++ b/tests/unit/bson/bson_append_regexp.c
@@ -0,0 +1,45 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_regex (void)
+{
+ bson *b;
+
+ b = bson_new ();
+ ok (bson_append_regex (b, "regex", "foo.*bar", "i"),
+ "bson_append_regex() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 23, "BSON regex element size check");
+ ok (memcmp (bson_data (b),
+ "\027\000\000\000\013\162\145\147\145\170\000\146\157\157\056"
+ "\052\142\141\162\000\151\000\000",
+ bson_size (b)) == 0,
+ "BSON regex element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_regex (b, "regex", "foo.*bar", NULL) == FALSE,
+ "bson_append_regex() without options should fail");
+ ok (bson_append_regex (b, "regex", NULL, "i") == FALSE,
+ "bson_append_regex() without a regex should fail");
+ ok (bson_append_regex (b, NULL, "foo.*bar", "i") == FALSE,
+ "bson_append_regex() should fail without a key name");
+ ok (bson_append_regex (NULL, "regex", "foo.*bar", "i") == FALSE,
+ "bson_append_regex() should fail without a BSON object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_regex (b, "regex", "foo.*bar", "i") == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (9, bson_regex);
diff --git a/tests/unit/bson/bson_append_string.c b/tests/unit/bson/bson_append_string.c
new file mode 100644
index 0000000..e6a73a7
--- /dev/null
+++ b/tests/unit/bson/bson_append_string.c
@@ -0,0 +1,61 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_string (void)
+{
+ bson *b;
+
+ /* Test #1: A single string element, with default size. */
+ b = bson_new ();
+ ok (bson_append_string (b, "hello", "world", -1),
+ "bson_append_string() works");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 22, "BSON string element size check");
+ ok (memcmp (bson_data (b),
+ "\026\000\000\000\002\150\145\154\154\157\000\006\000\000\000"
+ "\167\157\162\154\144\000\000",
+ bson_size (b)) == 0,
+ "BSON string element contents check");
+ bson_free (b);
+
+ /* Test #2: A single string element, with explicit length. */
+ b = bson_new ();
+ ok (bson_append_string (b, "goodbye",
+ "cruel world, this garbage is gone.",
+ strlen ("cruel world")),
+ "bson_append_string() with explicit length works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 30, "BSON string element size check, #2");
+ ok (memcmp (bson_data (b),
+ "\036\000\000\000\002\147\157\157\144\142\171\145\000\014\000"
+ "\000\000\143\162\165\145\154\040\167\157\162\154\144\000\000",
+ bson_size (b)) == 0,
+ "BSON string element contents check, #2");
+ bson_free (b);
+
+ /* Test #3: Negative test, passing invalid arguments. */
+ b = bson_new ();
+ ok (bson_append_string (b, "hello", "world", -42) == FALSE,
+ "bson_append_string() should fail with invalid length");
+ ok (bson_append_string (b, "hello", NULL, -1) == FALSE,
+ "bson_append_string() should fail without a string");
+ ok (bson_append_string (b, NULL, "world", -1) == FALSE,
+ "bson_append_string() should fail without a key name");
+ ok (bson_append_string (NULL, "hello", "world", -1) == FALSE,
+ "bson_append_string() should fail without a BSON object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_string (b, "hello", "world", -1) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (12, bson_string);
diff --git a/tests/unit/bson/bson_append_symbol.c b/tests/unit/bson/bson_append_symbol.c
new file mode 100644
index 0000000..6c16301
--- /dev/null
+++ b/tests/unit/bson/bson_append_symbol.c
@@ -0,0 +1,61 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_symbol (void)
+{
+ bson *b;
+
+ /* Test #1: A single symbol element, with default size. */
+ b = bson_new ();
+ ok (bson_append_symbol (b, "hello", "world", -1),
+ "bson_append_symbol() works");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 22, "BSON symbol element size check");
+ ok (memcmp (bson_data (b),
+ "\026\000\000\000\016\150\145\154\154\157\000\006\000\000\000"
+ "\167\157\162\154\144\000\000",
+ bson_size (b)) == 0,
+ "BSON symbol element contents check");
+ bson_free (b);
+
+ /* Test #2: A single symbol element, with explicit length. */
+ b = bson_new ();
+ ok (bson_append_symbol (b, "goodbye",
+ "cruel world, this garbage is gone.",
+ strlen ("cruel world")),
+ "bson_append_symbol() with explicit length works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 30, "BSON symbol element size check, #2");
+ ok (memcmp (bson_data (b),
+ "\036\000\000\000\016\147\157\157\144\142\171\145\000\014\000"
+ "\000\000\143\162\165\145\154\040\167\157\162\154\144\000\000",
+ bson_size (b)) == 0,
+ "BSON symbol element contents check, #2");
+ bson_free (b);
+
+ /* Test #3: Negative test, passing invalid arguments. */
+ b = bson_new ();
+ ok (bson_append_symbol (b, "hello", "world", -42) == FALSE,
+ "bson_append_symbol() should fail with invalid length");
+ ok (bson_append_symbol (b, "hello", NULL, -1) == FALSE,
+ "bson_append_symbol() should fail without a string");
+ ok (bson_append_symbol (b, NULL, "world", -1) == FALSE,
+ "bson_append_symbol() should fail without a key name");
+ ok (bson_append_symbol (NULL, "hello", "world", -1) == FALSE,
+ "bson_append_symbol() should fail without a BSON object");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_symbol (b, "hello", "world", -1) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (12, bson_symbol);
diff --git a/tests/unit/bson/bson_append_timestamp.c b/tests/unit/bson/bson_append_timestamp.c
new file mode 100644
index 0000000..4864ef4
--- /dev/null
+++ b/tests/unit/bson/bson_append_timestamp.c
@@ -0,0 +1,41 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_timestamp (void)
+{
+ bson *b;
+ gint64 l = 9876543210;
+
+ b = bson_new ();
+ ok (bson_append_timestamp (b, "ts", l), "bson_append_timestamp() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 17, "BSON timestamp element size check");
+ ok (memcmp (bson_data (b),
+ "\021\000\000\000\021\164\163\000\352\026\260\114\002\000\000"
+ "\000\000",
+ bson_size (b)) == 0,
+ "BSON timestamp element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_timestamp (b, NULL, l) == FALSE,
+ "bson_append_timestamp() with a NULL key should fail");
+ ok (bson_append_timestamp (NULL, "ts", l) == FALSE,
+ "bson_append_timestamp() without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_timestamp (b, "ts", l) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_timestamp);
diff --git a/tests/unit/bson/bson_append_utc_datetime.c b/tests/unit/bson/bson_append_utc_datetime.c
new file mode 100644
index 0000000..b2e38fb
--- /dev/null
+++ b/tests/unit/bson/bson_append_utc_datetime.c
@@ -0,0 +1,41 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_utc_datetime (void)
+{
+ bson *b;
+
+ b = bson_new ();
+ ok (bson_append_utc_datetime (b, "date", 1294860709000),
+ "bson_append_utc_datetime() works");
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 19, "BSON UTC datetime element size check");
+ ok (memcmp (bson_data (b),
+ "\023\000\000\000\011\144\141\164\145\000\210\154\266\173\055"
+ "\001\000\000\000",
+ bson_size (b)) == 0,
+ "BSON UTC datetime element contents check");
+
+ bson_free (b);
+
+ b = bson_new ();
+ ok (bson_append_utc_datetime (b, NULL, 1294860709000) == FALSE,
+ "bson_append_utc_datetime() with a NULL key should fail");
+ ok (bson_append_utc_datetime (NULL, "date", 1294860709000) == FALSE,
+ "bson_append_utc_datetime() without a BSON object should fail");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "BSON object should be empty");
+
+ ok (bson_append_utc_datetime (b, "date", 1294860709000) == FALSE,
+ "Appending to a finished element should fail");
+
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_utc_datetime);
diff --git a/tests/unit/bson/bson_build.c b/tests/unit/bson/bson_build.c
new file mode 100644
index 0000000..29693db
--- /dev/null
+++ b/tests/unit/bson/bson_build.c
@@ -0,0 +1,70 @@
+#include "bson.h"
+#include "tap.h"
+#include "test.h"
+
+#include <string.h>
+#include <glib.h>
+
+void
+test_bson_build (void)
+{
+ bson *b, *o, *d, *a, *scope;
+ guint8 oid[] = "1234567890ab";
+
+ a = bson_build (BSON_TYPE_INT32, "0", 32,
+ BSON_TYPE_INT64, "1", (gint64)-42,
+ BSON_TYPE_NONE);
+ bson_finish (a);
+ d = bson_build (BSON_TYPE_STRING, "name", "sub-document", -1,
+ BSON_TYPE_INT32, "answer", 42,
+ BSON_TYPE_NONE);
+ bson_finish (d);
+
+ scope = bson_build (BSON_TYPE_STRING, "v", "hello world", -1,
+ BSON_TYPE_NONE);
+ bson_finish (scope);
+
+ b = bson_build (BSON_TYPE_DOUBLE, "double", 3.14,
+ BSON_TYPE_STRING, "str", "hello world", -1,
+ BSON_TYPE_DOCUMENT, "doc", d,
+ BSON_TYPE_ARRAY, "array", a,
+ BSON_TYPE_BINARY, "binary0", BSON_BINARY_SUBTYPE_GENERIC,
+ (guint8 *)"foo\0bar", 7,
+ BSON_TYPE_OID, "_id", oid,
+ BSON_TYPE_BOOLEAN, "TRUE", FALSE,
+ BSON_TYPE_UTC_DATETIME, "date", 1294860709000,
+ BSON_TYPE_TIMESTAMP, "ts", 1294860709000,
+ BSON_TYPE_NULL, "null",
+ BSON_TYPE_REGEXP, "foobar", "s/foo.*bar/", "i",
+ BSON_TYPE_JS_CODE, "alert", "alert (\"hello world!\");", -1,
+ BSON_TYPE_SYMBOL, "sex", "Marilyn Monroe", -1,
+ BSON_TYPE_JS_CODE_W_SCOPE, "print", "alert (v);", -1, scope,
+ BSON_TYPE_INT32, "int32", 32,
+ BSON_TYPE_INT64, "int64", (gint64)-42,
+ BSON_TYPE_NONE);
+ bson_finish (b);
+ bson_free (d);
+ bson_free (a);
+ bson_free (scope);
+
+ o = test_bson_generate_full ();
+
+ cmp_ok (bson_size (b), "==", bson_size (o),
+ "bson_build() and hand crafted BSON object sizes match");
+ ok (memcmp (bson_data (b), bson_data (o), bson_size (b)) == 0,
+ "bson_build() and hand crafted BSON objects match");
+
+ bson_free (b);
+ bson_free (o);
+
+ b = bson_build (BSON_TYPE_UNDEFINED, BSON_TYPE_NONE);
+ ok (b == NULL,
+ "bson_build() should fail with an unsupported element type");
+ b = bson_build (BSON_TYPE_STRING, "str", "hello", -1,
+ BSON_TYPE_UNDEFINED,
+ BSON_TYPE_NONE);
+ ok (b == NULL,
+ "bson_build() should fail with an unsupported element type");
+}
+
+RUN_TEST (4, bson_build);
diff --git a/tests/unit/bson/bson_build_full.c b/tests/unit/bson/bson_build_full.c
new file mode 100644
index 0000000..08f2e45
--- /dev/null
+++ b/tests/unit/bson/bson_build_full.c
@@ -0,0 +1,71 @@
+#include "bson.h"
+#include "tap.h"
+#include "test.h"
+
+#include <string.h>
+#include <glib.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+void
+test_bson_build_full (void)
+{
+ bson *b, *o;
+
+ b = bson_build_full (BSON_TYPE_DOUBLE, "double", FALSE, 3.14,
+ BSON_TYPE_STRING, "str", FALSE, "hello world", -1,
+ BSON_TYPE_DOCUMENT, "doc", TRUE,
+ bson_build (BSON_TYPE_STRING, "name", "sub-document", -1,
+ BSON_TYPE_INT32, "answer", 42,
+ BSON_TYPE_NONE),
+ BSON_TYPE_ARRAY, "array", TRUE,
+ bson_build (BSON_TYPE_INT32, "0", 32,
+ BSON_TYPE_INT64, "1", (gint64)-42,
+ BSON_TYPE_NONE),
+ BSON_TYPE_BINARY, "binary0", FALSE, BSON_BINARY_SUBTYPE_GENERIC,
+ "foo\0bar", 7,
+ BSON_TYPE_OID, "_id", FALSE, "1234567890ab",
+ BSON_TYPE_BOOLEAN, "TRUE", FALSE, FALSE,
+ BSON_TYPE_UTC_DATETIME, "date", FALSE, 1294860709000,
+ BSON_TYPE_TIMESTAMP, "ts", FALSE, 1294860709000,
+ BSON_TYPE_NULL, "null", FALSE,
+ BSON_TYPE_REGEXP, "foobar", FALSE, "s/foo.*bar/", "i",
+ BSON_TYPE_JS_CODE, "alert", FALSE, "alert (\"hello world!\");", -1,
+ BSON_TYPE_SYMBOL, "sex", FALSE, "Marilyn Monroe", -1,
+ BSON_TYPE_JS_CODE_W_SCOPE, "print", TRUE, "alert (v);", -1,
+ bson_build (BSON_TYPE_STRING, "v", "hello world", -1,
+ BSON_TYPE_NONE),
+ BSON_TYPE_INT32, "int32", FALSE, 32,
+ BSON_TYPE_INT64, "int64", FALSE, (gint64)-42,
+ BSON_TYPE_NONE);
+ bson_finish (b);
+
+ o = test_bson_generate_full ();
+
+ cmp_ok (bson_size (b), "==", bson_size (o),
+ "bson_build_full() and hand crafted BSON object sizes match");
+
+ ok (memcmp (bson_data (b), bson_data (o), bson_size (b)) == 0,
+ "bson_build_full() and hand crafted BSON objects match");
+
+ bson_free (b);
+ bson_free (o);
+
+ b = bson_build_full (BSON_TYPE_UNDEFINED, "undef", FALSE,
+ BSON_TYPE_NONE);
+ ok (b == NULL,
+ "bson_build_full() should fail with an unsupported element type");
+ b = bson_build_full (BSON_TYPE_STRING, "str", FALSE, "hello", -1,
+ BSON_TYPE_UNDEFINED, "undef", FALSE,
+ BSON_TYPE_NONE);
+ ok (b == NULL,
+ "bson_build_full() should fail with an unsupported element type");
+
+}
+
+RUN_TEST (4, bson_build_full);
diff --git a/tests/unit/bson/bson_cursor_find.c b/tests/unit/bson/bson_cursor_find.c
new file mode 100644
index 0000000..db1afd5
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_find.c
@@ -0,0 +1,39 @@
+#include "test.h"
+#include "mongo.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_find (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ b = test_bson_generate_full ();
+ c = bson_find (b, "TRUE");
+
+ ok (bson_cursor_find (c, NULL) == FALSE,
+ "bson_cursor_find() should fail with a NULL key");
+ ok (bson_cursor_find (NULL, "int32") == FALSE,
+ "bson_cursor_find() should fail with a NULL cursor");
+
+ ok (bson_cursor_find (c, "sex") == TRUE,
+ "bson_cursor_find() works");
+
+ ok (bson_cursor_find (c, "str") == TRUE,
+ "bson_cursor_find() should wrap over if neccessary");
+
+ ok (bson_cursor_find (c, "-invalid-key-") == FALSE,
+ "bson_cursor_find() should fail when the key is not found");
+
+ ok (bson_cursor_find (c, "int64") == TRUE,
+ "bson_cursor_find() works, even after a previous failure");
+
+ ok (bson_cursor_find (c, "int6") == FALSE,
+ "bson_cursor_find() does not match prefixes");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_find);
diff --git a/tests/unit/bson/bson_cursor_find_next.c b/tests/unit/bson/bson_cursor_find_next.c
new file mode 100644
index 0000000..96d7f0e
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_find_next.c
@@ -0,0 +1,33 @@
+#include "test.h"
+#include "mongo.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_find_next (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ b = test_bson_generate_full ();
+ c = bson_find (b, "TRUE");
+
+ ok (bson_cursor_find_next (c, NULL) == FALSE,
+ "bson_cursor_find_next() should fail with a NULL key");
+ ok (bson_cursor_find_next (NULL, "int32") == FALSE,
+ "bson_cursor_find_next() should fail with a NULL cursor");
+
+ ok (bson_cursor_find_next (c, "sex") == TRUE,
+ "bson_cursor_find_next() works");
+
+ ok (bson_cursor_find_next (c, "str") == FALSE,
+ "bson_cursor_find_next() should fail when the key is not found");
+
+ ok (bson_cursor_find_next (c, "int64") == TRUE,
+ "bson_cursor_find_next() works, even after a previous failure");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (5, bson_cursor_find_next);
diff --git a/tests/unit/bson/bson_cursor_get_array.c b/tests/unit/bson/bson_cursor_get_array.c
new file mode 100644
index 0000000..becdc5d
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_array.c
@@ -0,0 +1,44 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_array (void)
+{
+ bson *b, *a = NULL;
+ bson_cursor *c;
+
+ ok (bson_cursor_get_array (NULL, &a) == FALSE,
+ "bson_cursor_get_array() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_array (c, NULL) == FALSE,
+ "bson_cursor_get_array() with a NULL destination fails");
+ ok (bson_cursor_get_array (c, &a) == FALSE,
+ "bson_cursor_get_array() at the initial position fails");
+ ok (a == NULL,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "array");
+ ok (bson_cursor_get_array (c, &a),
+ "bson_cursor_get_array() works");
+ cmp_ok (bson_size (a), ">", 0,
+ "the returned document is finished");
+ bson_free (a);
+
+ bson_cursor_next (c);
+
+ ok (bson_cursor_get_array (c, &a) == FALSE,
+ "bson_cursor_get_array() fails if the cursor points to "
+ "non-array data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_array);
diff --git a/tests/unit/bson/bson_cursor_get_binary.c b/tests/unit/bson/bson_cursor_get_binary.c
new file mode 100644
index 0000000..3ec0dc3
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_binary.c
@@ -0,0 +1,60 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_binary (void)
+{
+ bson *b;
+ bson_cursor *c;
+ const guint8 *d = (guint8 *)"deadbeef";
+ bson_binary_subtype t = 0xff;
+ gint32 s = -1;
+
+ ok (bson_cursor_get_binary (NULL, &t, &d, &s) == FALSE,
+ "bson_cursor_get_binary() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_binary (c, NULL, NULL, NULL) == FALSE,
+ "bson_cursor_get_binary() with NULL destinations fails");
+ ok (bson_cursor_get_binary (c, NULL, &d, &s) == FALSE,
+ "bson_cursor_get_binary() with a NULL subtype destination fails");
+ ok (bson_cursor_get_binary (c, &t, NULL, &s) == FALSE,
+ "bson_cursor_get_binary() with a NULL binary destination fails");
+ ok (bson_cursor_get_binary (c, &t, &d, NULL) == FALSE,
+ "bson_cursor_get_binary() with a NULL size destination fails");
+ ok (bson_cursor_get_binary (c, &t, &d, &s) == FALSE,
+ "bson_cursor_get_binary() at the initial position fails");
+ ok (memcmp (d, "deadbeef", sizeof ("deadbeef")) == 0,
+ "binary destination remains unchanged after failed cursor operations");
+ cmp_ok (t, "==", 0xff,
+ "subtype destination remains unchanged after failed cursor "
+ "operations");
+ cmp_ok (s, "==", -1,
+ "size destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "binary0");
+ ok (bson_cursor_get_binary (c, &t, &d, &s),
+ "bson_cursor_get_binary() works");
+ cmp_ok (s, "==", 7,
+ "bson_cursor_get_binary() returns the correct result");
+ ok (memcmp (d, "foo\0bar", s) == 0,
+ "bson_cursor_get_binary() returns the correct result");
+ cmp_ok (t, "==", BSON_BINARY_SUBTYPE_GENERIC,
+ "bson_cursor_get_binary() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_binary (c, &t, &d, &s) == FALSE,
+ "bson_cursor_get_binary() should fail when the cursor points to "
+ "non-binary data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (14, bson_cursor_get_binary);
diff --git a/tests/unit/bson/bson_cursor_get_boolean.c b/tests/unit/bson/bson_cursor_get_boolean.c
new file mode 100644
index 0000000..079d2b2
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_boolean.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_boolean (void)
+{
+ bson *b;
+ bson_cursor *c;
+ gboolean d = TRUE;
+
+ ok (bson_cursor_get_boolean (NULL, &d) == FALSE,
+ "bson_cursor_get_boolean() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_boolean (c, NULL) == FALSE,
+ "bson_cursor_get_boolean() with a NULL destination fails");
+ ok (bson_cursor_get_boolean (c, &d) == FALSE,
+ "bson_cursor_get_boolean() at the initial position fails");
+ cmp_ok (d, "==", TRUE,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "TRUE");
+ ok (bson_cursor_get_boolean (c, &d),
+ "bson_cursor_get_boolean() works");
+ cmp_ok (d, "==", FALSE,
+ "bson_cursor_get_boolean() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_boolean (c, &d) == FALSE,
+ "bson_cursor_get_boolean() should fail when the cursor points to "
+ "non-double data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_boolean);
diff --git a/tests/unit/bson/bson_cursor_get_document.c b/tests/unit/bson/bson_cursor_get_document.c
new file mode 100644
index 0000000..107ecf5
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_document.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_document (void)
+{
+ bson *b, *d = NULL;
+ bson_cursor *c;
+
+ ok (bson_cursor_get_document (NULL, &d) == FALSE,
+ "bson_cursor_get_document() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_document (c, NULL) == FALSE,
+ "bson_cursor_get_document() with a NULL destination fails");
+ ok (bson_cursor_get_document (c, &d) == FALSE,
+ "bson_cursor_get_document() at the initial position fails");
+ ok (d == NULL,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "doc");
+ ok (bson_cursor_get_document (c, &d),
+ "bson_cursor_get_document() works");
+ cmp_ok (bson_size (d), ">", 0,
+ "the returned document is finished");
+ bson_free (d);
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_document (c, &d) == FALSE,
+ "bson_cursor_get_document() fails if the cursor points to "
+ "non-document data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_document);
diff --git a/tests/unit/bson/bson_cursor_get_double.c b/tests/unit/bson/bson_cursor_get_double.c
new file mode 100644
index 0000000..7b5cdff
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_double.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_double (void)
+{
+ bson *b;
+ bson_cursor *c;
+ gdouble d = 12.34;
+
+ ok (bson_cursor_get_double (NULL, &d) == FALSE,
+ "bson_cursor_get_double() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_double (c, NULL) == FALSE,
+ "bson_cursor_get_double() with a NULL destination fails");
+ ok (bson_cursor_get_double (c, &d) == FALSE,
+ "bson_cursor_get_double() at the initial position fails");
+ ok (d == 12.34,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "double");
+ ok (bson_cursor_get_double (c, &d),
+ "bson_cursor_get_double() works");
+ ok (d == 3.14,
+ "bson_cursor_get_double() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_double (c, &d) == FALSE,
+ "bson_cursor_get_double() should fail when the cursor points to "
+ "non-double data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_double);
diff --git a/tests/unit/bson/bson_cursor_get_int32.c b/tests/unit/bson/bson_cursor_get_int32.c
new file mode 100644
index 0000000..caea604
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_int32.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_int32 (void)
+{
+ bson *b;
+ bson_cursor *c;
+ gint d = 12345;
+
+ ok (bson_cursor_get_int32 (NULL, &d) == FALSE,
+ "bson_cursor_get_int32() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_int32 (c, NULL) == FALSE,
+ "bson_cursor_get_int32() with a NULL destination fails");
+ ok (bson_cursor_get_int32 (c, &d) == FALSE,
+ "bson_cursor_get_int32() at the initial position fails");
+ cmp_ok (d, "==", 12345,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "int32");
+ ok (bson_cursor_get_int32 (c, &d),
+ "bson_cursor_get_int32() works");
+ cmp_ok (d, "==", 32,
+ "bson_cursor_get_int32() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_int32 (c, &d) == FALSE,
+ "bson_cursor_get_int32() should fail when the cursor points to "
+ "non-int32 data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_int32);
diff --git a/tests/unit/bson/bson_cursor_get_int64.c b/tests/unit/bson/bson_cursor_get_int64.c
new file mode 100644
index 0000000..d1c80f5
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_int64.c
@@ -0,0 +1,45 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_int64 (void)
+{
+ bson *b;
+ bson_cursor *c;
+ gint64 d = (gint64)987654;
+
+ ok (bson_cursor_get_int64 (NULL, &d) == FALSE,
+ "bson_cursor_get_int64() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_int64 (c, NULL) == FALSE,
+ "bson_cursor_get_int64() with a NULL destination fails");
+ ok (bson_cursor_get_int64 (c, &d) == FALSE,
+ "bson_cursor_get_int64() at the initial position fails");
+ cmp_ok (d, "==", 987654,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "int64");
+ ok (bson_cursor_get_int64 (c, &d),
+ "bson_cursor_get_int64() works");
+ cmp_ok (d, "==", (gint64)-42,
+ "bson_cursor_get_int64() returns the correct result");
+
+ bson_cursor_free (c);
+
+ c = bson_find (b, "double");
+ ok (bson_cursor_get_int64 (c, &d) == FALSE,
+ "bson_cursor_get_int64() should fail when the cursor points to "
+ "non-int64 data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_int64);
diff --git a/tests/unit/bson/bson_cursor_get_javascript.c b/tests/unit/bson/bson_cursor_get_javascript.c
new file mode 100644
index 0000000..4231cbd
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_javascript.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_javascript (void)
+{
+ bson *b;
+ bson_cursor *c;
+ const gchar *s = "deadbeef";
+
+ ok (bson_cursor_get_javascript (NULL, &s) == FALSE,
+ "bson_cursor_get_javascript() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_javascript (c, NULL) == FALSE,
+ "bson_cursor_get_javascript() with a NULL destination fails");
+ ok (bson_cursor_get_javascript (c, &s) == FALSE,
+ "bson_cursor_get_javascript() at the initial position fails");
+ is (s, "deadbeef",
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "alert");
+ ok (bson_cursor_get_javascript (c, &s),
+ "bson_cursor_get_javascript() works");
+ is (s, "alert (\"hello world!\");",
+ "bson_cursor_get_javascript() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_javascript (c, &s) == FALSE,
+ "bson_cursor_get_javascript() should fail when the cursor points to "
+ "non-javascript data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_javascript);
diff --git a/tests/unit/bson/bson_cursor_get_javascript_w_scope.c b/tests/unit/bson/bson_cursor_get_javascript_w_scope.c
new file mode 100644
index 0000000..2e0b9ca
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_javascript_w_scope.c
@@ -0,0 +1,57 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_javascript_w_scope (void)
+{
+ bson *b, *scope = NULL, *valid;
+ bson_cursor *c;
+ const gchar *s = "deadbeef";
+
+ ok (bson_cursor_get_javascript_w_scope (NULL, &s, &scope) == FALSE,
+ "bson_cursor_get_javascript_w_scope() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_javascript_w_scope (c, NULL, &scope) == FALSE,
+ "bson_cursor_get_javascript_w_scope() with a NULL js destination fails");
+ ok (bson_cursor_get_javascript_w_scope (c, &s, NULL) == FALSE,
+ "bson_cursor_get_javascript_w_scope() with a NULL scope destinatin fails");
+ ok (bson_cursor_get_javascript_w_scope (c, &s, &scope) == FALSE,
+ "bson_cursor_get_javascript_w_scope() at the initial position fails");
+ is (s, "deadbeef",
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "print");
+ ok (bson_cursor_get_javascript_w_scope (c, &s, &scope),
+ "bson_cursor_get_javascript_w_scope() works");
+ is (s, "alert (v);",
+ "bson_cursor_get_javascript_w_scope() returns the correct result");
+
+ valid = bson_new ();
+ bson_append_string (valid, "v", "hello world", -1);
+ bson_finish (valid);
+
+ cmp_ok (bson_size (scope), "==", bson_size (valid),
+ "The returned scope's length is correct");
+ ok (memcmp (bson_data (scope), bson_data (valid),
+ bson_size (scope)) == 0,
+ "The returned scope is correct");
+ bson_free (valid);
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_javascript_w_scope (c, &s, &scope) == FALSE,
+ "bson_cursor_get_javascript_w_scope() should fail when the cursor "
+ "points to non-javascript data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+ bson_free (scope);
+}
+
+RUN_TEST (10, bson_cursor_get_javascript_w_scope);
diff --git a/tests/unit/bson/bson_cursor_get_oid.c b/tests/unit/bson/bson_cursor_get_oid.c
new file mode 100644
index 0000000..5c2d77b
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_oid.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_oid (void)
+{
+ bson *b;
+ bson_cursor *c;
+ const gchar *s = "abababababab";
+
+ ok (bson_cursor_get_oid (NULL, (const guint8 **)&s) == FALSE,
+ "bson_cursor_get_oid() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_oid (c, NULL) == FALSE,
+ "bson_cursor_get_oid() with a NULL destination fails");
+ ok (bson_cursor_get_oid (c, (const guint8 **)&s) == FALSE,
+ "bson_cursor_get_oid() at the initial position fails");
+ ok (memcmp (s, "abababababab", 12) == 0,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "_id");
+ ok (bson_cursor_get_oid (c, (const guint8 **)&s),
+ "bson_cursor_get_oid() works");
+ ok (memcmp (s, "1234567890ab", 12) == 0,
+ "bson_cursor_get_oid() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_oid (c, (const guint8 **)&s) == FALSE,
+ "bson_cursor_get_oid() should fail when the cursor points to "
+ "non-oid data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_oid);
diff --git a/tests/unit/bson/bson_cursor_get_regex.c b/tests/unit/bson/bson_cursor_get_regex.c
new file mode 100644
index 0000000..59edefd
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_regex.c
@@ -0,0 +1,52 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_regex (void)
+{
+ bson *b;
+ bson_cursor *c;
+ const gchar *r = "deadbeef";
+ const gchar *o = "g";
+
+ ok (bson_cursor_get_regex (NULL, &r, &o) == FALSE,
+ "bson_cursor_get_regex() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_regex (c, NULL, NULL) == FALSE,
+ "bson_cursor_get_regex() with NULL destinations fails");
+ ok (bson_cursor_get_regex (c, &r, NULL) == FALSE,
+ "bson_cursor_get_regex() with a NULL option destination fails");
+ ok (bson_cursor_get_regex (c, NULL, &o) == FALSE,
+ "bson_cursor_get_regex() with a NULL regex destination fails");
+ ok (bson_cursor_get_regex (c, &r, &o) == FALSE,
+ "bson_cursor_get_regex() at the initial position fails");
+ is (r, "deadbeef",
+ "regex destination remains unchanged after failed cursor operations");
+ is (o, "g",
+ "options destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "foobar");
+ ok (bson_cursor_get_regex (c, &r, &o),
+ "bson_cursor_get_regex() works");
+ is (r, "s/foo.*bar/",
+ "bson_cursor_get_regex() returns the correct result");
+ is (o, "i",
+ "bson_cursor_get_regex() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_regex (c, &r, &o) == FALSE,
+ "bson_cursor_get_regex() should fail when the cursor points to "
+ "non-regex data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (11, bson_cursor_get_regex);
diff --git a/tests/unit/bson/bson_cursor_get_string.c b/tests/unit/bson/bson_cursor_get_string.c
new file mode 100644
index 0000000..18662bb
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_string.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_string (void)
+{
+ bson *b;
+ bson_cursor *c;
+ const gchar *s = "deadbeef";
+
+ ok (bson_cursor_get_string (NULL, &s) == FALSE,
+ "bson_cursor_get_string() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_string (c, NULL) == FALSE,
+ "bson_cursor_get_string() with a NULL destination fails");
+ ok (bson_cursor_get_string (c, &s) == FALSE,
+ "bson_cursor_get_string() at the initial position fails");
+ is (s, "deadbeef",
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "str");
+ ok (bson_cursor_get_string (c, &s),
+ "bson_cursor_get_string() works");
+ is (s, "hello world",
+ "bson_cursor_get_string() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_string (c, &s) == FALSE,
+ "bson_cursor_get_string() should fail when the cursor points to "
+ "non-string data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_string);
diff --git a/tests/unit/bson/bson_cursor_get_symbol.c b/tests/unit/bson/bson_cursor_get_symbol.c
new file mode 100644
index 0000000..785e71b
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_symbol.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_symbol (void)
+{
+ bson *b;
+ bson_cursor *c;
+ const gchar *s = "deadbeef";
+
+ ok (bson_cursor_get_symbol (NULL, &s) == FALSE,
+ "bson_cursor_get_symbol() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_symbol (c, NULL) == FALSE,
+ "bson_cursor_get_symbol() with a NULL destination fails");
+ ok (bson_cursor_get_symbol (c, &s) == FALSE,
+ "bson_cursor_get_symbol() at the initial position fails");
+ is (s, "deadbeef",
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "sex");
+ ok (bson_cursor_get_symbol (c, &s),
+ "bson_cursor_get_symbol() works");
+ is (s, "Marilyn Monroe",
+ "bson_cursor_get_symbol() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_symbol (c, &s) == FALSE,
+ "bson_cursor_get_symbol() should fail when the cursor points to "
+ "non-symbol data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_symbol);
diff --git a/tests/unit/bson/bson_cursor_get_timestamp.c b/tests/unit/bson/bson_cursor_get_timestamp.c
new file mode 100644
index 0000000..3bfc86c
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_timestamp.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_timestamp (void)
+{
+ bson *b;
+ bson_cursor *c;
+ gint64 d = (gint64)987654;
+
+ ok (bson_cursor_get_timestamp (NULL, &d) == FALSE,
+ "bson_cursor_get_timestamp() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_timestamp (c, NULL) == FALSE,
+ "bson_cursor_get_timestamp() with a NULL destination fails");
+ ok (bson_cursor_get_timestamp (c, &d) == FALSE,
+ "bson_cursor_get_timestamp() at the initial position fails");
+ cmp_ok (d, "==", 987654,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "ts");
+ ok (bson_cursor_get_timestamp (c, &d),
+ "bson_cursor_get_timestamp() works");
+ ok (d == 1294860709000,
+ "bson_cursor_get_timestamp() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_timestamp (c, &d) == FALSE,
+ "bson_cursor_get_timestamp() should fail when the cursor points to "
+ "non-timestamp data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_timestamp);
diff --git a/tests/unit/bson/bson_cursor_get_utc_datetime.c b/tests/unit/bson/bson_cursor_get_utc_datetime.c
new file mode 100644
index 0000000..70e1332
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_get_utc_datetime.c
@@ -0,0 +1,43 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_get_utc_datetime (void)
+{
+ bson *b;
+ bson_cursor *c;
+ gint64 d = (gint64)987654;
+
+ ok (bson_cursor_get_utc_datetime (NULL, &d) == FALSE,
+ "bson_cursor_get_utc_datetime() with a NULL cursor fails");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_get_utc_datetime (c, NULL) == FALSE,
+ "bson_cursor_get_utc_datetime() with a NULL destination fails");
+ ok (bson_cursor_get_utc_datetime (c, &d) == FALSE,
+ "bson_cursor_get_utc_datetime() at the initial position fails");
+ cmp_ok (d, "==", 987654,
+ "destination remains unchanged after failed cursor operations");
+ bson_cursor_free (c);
+
+ c = bson_find (b, "date");
+ ok (bson_cursor_get_utc_datetime (c, &d),
+ "bson_cursor_get_utc_datetime() works");
+ ok (d == 1294860709000,
+ "bson_cursor_get_utc_datetime() returns the correct result");
+
+ bson_cursor_next (c);
+ ok (bson_cursor_get_utc_datetime (c, &d) == FALSE,
+ "bson_cursor_get_utc_datetime() should fail when the cursor points to "
+ "non-datetime data");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (7, bson_cursor_get_utc_datetime);
diff --git a/tests/unit/bson/bson_cursor_key.c b/tests/unit/bson/bson_cursor_key.c
new file mode 100644
index 0000000..7db98b6
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_key.c
@@ -0,0 +1,30 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_key (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ is (bson_cursor_key (NULL), NULL,
+ "bson_cursor_key(NULL) should fail");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ is (bson_cursor_key (c), NULL,
+ "bson_cursor_key() should fail at the initial position");
+ bson_cursor_next (c);
+
+ is (bson_cursor_key (c), "double",
+ "bson_cursor_key() works");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (3, bson_cursor_key);
diff --git a/tests/unit/bson/bson_cursor_new.c b/tests/unit/bson/bson_cursor_new.c
new file mode 100644
index 0000000..7bcb32b
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_new.c
@@ -0,0 +1,28 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_new (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ ok (bson_cursor_new (NULL) == NULL,
+ "bson_cursor_new(NULL) should fail");
+
+ b = bson_new ();
+ ok (bson_cursor_new (b) == NULL,
+ "bson_cursor_new() should fail with an unfinished BSON object");
+ bson_free (b);
+
+ b = test_bson_generate_full ();
+ ok ((c = bson_cursor_new (b)) != NULL,
+ "bson_cursor_new() works");
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (3, bson_cursor_new);
diff --git a/tests/unit/bson/bson_cursor_next.c b/tests/unit/bson/bson_cursor_next.c
new file mode 100644
index 0000000..a2fc137
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_next.c
@@ -0,0 +1,42 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_next (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ ok (bson_cursor_next (NULL) == FALSE,
+ "bson_cursor_next (NULL) should fail");
+
+ b = bson_new ();
+ bson_finish (b);
+ c = bson_cursor_new (b);
+
+ ok (bson_cursor_next (c) == FALSE,
+ "bson_cursor_next() should fail with an empty document");
+
+ bson_cursor_free (c);
+ bson_free (b);
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+ ok (bson_cursor_next (c),
+ "initial bson_cursor_next() works");
+ ok (bson_cursor_next (c),
+ "subsequent bson_cursor_next() works too");
+
+ while (bson_cursor_next (c)) ;
+
+ ok (bson_cursor_next (c) == FALSE,
+ "bson_cursor_next() fails after the end of the BSON object");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (5, bson_cursor_next);
diff --git a/tests/unit/bson/bson_cursor_type.c b/tests/unit/bson/bson_cursor_type.c
new file mode 100644
index 0000000..86be005
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_type.c
@@ -0,0 +1,30 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_type (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ cmp_ok (bson_cursor_type (NULL), "==", BSON_TYPE_NONE,
+ "bson_cursor_type(NULL) should fail");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_NONE,
+ "bson_cursor_type() should fail at the beginning of the BSON "
+ "object");
+ bson_cursor_next (c);
+ cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_DOUBLE,
+ "bson_cursor_type() works");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (3, bson_cursor_type);
diff --git a/tests/unit/bson/bson_cursor_type_as_string.c b/tests/unit/bson/bson_cursor_type_as_string.c
new file mode 100644
index 0000000..8ee6fea
--- /dev/null
+++ b/tests/unit/bson/bson_cursor_type_as_string.c
@@ -0,0 +1,31 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_cursor_type_as_string (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ is (bson_cursor_type_as_string (NULL), NULL,
+ "bson_cursor_type_as_string(NULL) should fail");
+
+ b = test_bson_generate_full ();
+ c = bson_cursor_new (b);
+
+ is (bson_cursor_type_as_string (c), NULL,
+ "bson_cursor_type_as_string() should fail at the initial position");
+ bson_cursor_next (c);
+
+ is (bson_cursor_type_as_string (c),
+ bson_type_as_string (bson_cursor_type (c)),
+ "bson_cursor_type_as_string() works");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (3, bson_cursor_type_as_string);
diff --git a/tests/unit/bson/bson_empty.c b/tests/unit/bson/bson_empty.c
new file mode 100644
index 0000000..69d840a
--- /dev/null
+++ b/tests/unit/bson/bson_empty.c
@@ -0,0 +1,22 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_empty (void)
+{
+ bson *b;
+
+ b = bson_new ();
+ bson_finish (b);
+
+ cmp_ok (bson_size (b), "==", 5, "Empty BSON size check");
+ ok (memcmp (bson_data (b), "\005\000\000\000\000", bson_size (b)) == 0,
+ "Empty BSON contents check");
+
+ bson_free (b);
+}
+
+RUN_TEST (2, bson_empty)
diff --git a/tests/unit/bson/bson_find.c b/tests/unit/bson/bson_find.c
new file mode 100644
index 0000000..54e8767
--- /dev/null
+++ b/tests/unit/bson/bson_find.c
@@ -0,0 +1,34 @@
+#include "tap.h"
+#include "test.h"
+#include "bson.h"
+
+#include <string.h>
+
+void
+test_bson_find (void)
+{
+ bson *b;
+ bson_cursor *c;
+
+ ok (bson_find (NULL, NULL) == NULL,
+ "bson_find() with NULL parameters should fail");
+ ok (bson_find (NULL, "key") == NULL,
+ "bson_find() with a NULL BSON object should fail");
+ b = bson_new ();
+ ok (bson_find (b, "key") == NULL,
+ "bson_find() with an unfinished BSON object should fail");
+ bson_free (b);
+
+ b = test_bson_generate_full ();
+ ok (bson_find (b, NULL) == FALSE,
+ "bson_find() with a NULL key should fail");
+ ok (bson_find (b, "__invalid__") == FALSE,
+ "bson_find() with a non-existent key should fail");
+ ok ((c = bson_find (b, "alert")) != NULL,
+ "bson_find() works");
+
+ bson_cursor_free (c);
+ bson_free (b);
+}
+
+RUN_TEST (6, bson_find);
diff --git a/tests/unit/bson/bson_new.c b/tests/unit/bson/bson_new.c
new file mode 100644
index 0000000..3149027
--- /dev/null
+++ b/tests/unit/bson/bson_new.c
@@ -0,0 +1,28 @@
+#include "bson.h"
+#include "test.h"
+#include "tap.h"
+
+#include <string.h>
+
+void
+test_bson_new (void)
+{
+ bson *b;
+
+ ok ((b = bson_new ()) != NULL, "bson_new() works");
+ ok (bson_data (b) == NULL,
+ "bson_data() with an unfished object should fail");
+ ok (bson_size (b) == -1,
+ "bson_size() with an unfinished object should fail");
+ ok (bson_finish (b), "bson_finish() works");
+ ok (bson_finish (b),
+ "bson_finish() works on an already finished object too");
+ bson_free (b);
+
+ ok (bson_size (NULL) == -1, "bson_size(NULL) works correctly");
+ ok (bson_data (NULL) == NULL, "bson_data(NULL) works correctly");
+ ok (bson_finish (NULL) == FALSE, "bson_finish(NULL) works correctly");
+ bson_free (NULL);
+}
+
+RUN_TEST (8, bson_new);
diff --git a/tests/unit/bson/bson_new_from_data.c b/tests/unit/bson/bson_new_from_data.c
new file mode 100644
index 0000000..740cb6e
--- /dev/null
+++ b/tests/unit/bson/bson_new_from_data.c
@@ -0,0 +1,46 @@
+#include "bson.h"
+#include "test.h"
+#include "tap.h"
+
+#include <string.h>
+
+void
+test_bson_new_from_data (void)
+{
+ bson *orig, *new;
+
+ orig = test_bson_generate_full ();
+
+ ok (bson_new_from_data (NULL, 0) == NULL,
+ "bson_new_from_data (NULL, 0) fails");
+ ok (bson_new_from_data (NULL, bson_size (orig)) == NULL,
+ "bson_new_from_data (NULL, size) fails");
+ ok (bson_new_from_data (bson_data (orig), 0) == NULL,
+ "bson_new_from_data (orig, 0) fails");
+ ok (bson_new_from_data (bson_data (orig), -1) == NULL,
+ "bson_new_from_data (orig, -1) fails");
+ ok (bson_new_from_data (NULL, -1) == NULL,
+ "bson_new_from_data (NULL, -1) fails");
+
+ ok ((new = bson_new_from_data (bson_data (orig),
+ bson_size (orig) - 1)) != NULL,
+ "bson_new_from_data() works");
+ cmp_ok (bson_size (new), "==", -1,
+ "Copied object is unfinished");
+ bson_finish (new);
+
+ ok (orig != new, "Copied BSON object is not the same as the original");
+
+ cmp_ok (bson_size (orig), "==", bson_size (new),
+ "Copied (& finished) object has the same size as the original");
+ ok (bson_data (orig) != bson_data (new),
+ "The copied data is not the same as the original");
+ ok (memcmp (bson_data (orig), bson_data (new),
+ bson_size (orig)) == 0,
+ "The copied data is identical to the original");
+
+ bson_free (orig);
+ bson_free (new);
+}
+
+RUN_TEST (11, bson_new_from_data);
diff --git a/tests/unit/bson/bson_reset.c b/tests/unit/bson/bson_reset.c
new file mode 100644
index 0000000..23f2ce6
--- /dev/null
+++ b/tests/unit/bson/bson_reset.c
@@ -0,0 +1,27 @@
+#include "bson.h"
+#include "test.h"
+#include "tap.h"
+
+void
+test_bson_reset (void)
+{
+ bson *b;
+
+ b = test_bson_generate_full ();
+
+ cmp_ok (bson_size (b), "!=", -1,
+ "bson_size() != -1 on a non-empty document");
+ ok (bson_reset (b), "bson_reset() works");
+ cmp_ok (bson_size (b), "==", -1,
+ "bson_size() on a reseted object returns an error");
+ bson_finish (b);
+ cmp_ok (bson_size (b), "==", 5,
+ "bson_size() on a reseted & finished object matches the "
+ "size of an empty document");
+ bson_free (b);
+
+ ok (bson_reset (NULL) == FALSE,
+ "bson_reset(NULL) should fail");
+}
+
+RUN_TEST (5, bson_reset);
diff --git a/tests/unit/bson/bson_type_as_string.c b/tests/unit/bson/bson_type_as_string.c
new file mode 100644
index 0000000..35e8210
--- /dev/null
+++ b/tests/unit/bson/bson_type_as_string.c
@@ -0,0 +1,40 @@
+#include "bson.h"
+#include "test.h"
+#include "tap.h"
+
+#include <string.h>
+
+#define CHECK_TYPE(t) \
+ is (bson_type_as_string (t), #t, \
+ "bson_type_as_string(%s) works", #t)
+
+void
+test_bson_type_as_string (void)
+{
+ CHECK_TYPE (BSON_TYPE_NONE);
+ CHECK_TYPE (BSON_TYPE_DOUBLE);
+ CHECK_TYPE (BSON_TYPE_STRING);
+ CHECK_TYPE (BSON_TYPE_DOCUMENT);
+ CHECK_TYPE (BSON_TYPE_ARRAY);
+ CHECK_TYPE (BSON_TYPE_BINARY);
+ CHECK_TYPE (BSON_TYPE_UNDEFINED);
+ CHECK_TYPE (BSON_TYPE_OID);
+ CHECK_TYPE (BSON_TYPE_BOOLEAN);
+ CHECK_TYPE (BSON_TYPE_UTC_DATETIME);
+ CHECK_TYPE (BSON_TYPE_NULL);
+ CHECK_TYPE (BSON_TYPE_REGEXP);
+ CHECK_TYPE (BSON_TYPE_DBPOINTER);
+ CHECK_TYPE (BSON_TYPE_JS_CODE);
+ CHECK_TYPE (BSON_TYPE_SYMBOL);
+ CHECK_TYPE (BSON_TYPE_JS_CODE_W_SCOPE);
+ CHECK_TYPE (BSON_TYPE_INT32);
+ CHECK_TYPE (BSON_TYPE_TIMESTAMP);
+ CHECK_TYPE (BSON_TYPE_INT64);
+ CHECK_TYPE (BSON_TYPE_MIN);
+ CHECK_TYPE (BSON_TYPE_MAX);
+
+ ok (bson_type_as_string (42) == NULL,
+ "bson_type_as_string() returns NULL on invalid type.");
+}
+
+RUN_TEST (22, bson_type_as_string);
diff --git a/tests/unit/bson/bson_validate_key.c b/tests/unit/bson/bson_validate_key.c
new file mode 100644
index 0000000..126b1fd
--- /dev/null
+++ b/tests/unit/bson/bson_validate_key.c
@@ -0,0 +1,36 @@
+#include "tap.h"
+#include "test.h"
+
+#include <errno.h>
+#include <bson.h>
+#include <string.h>
+
+void
+test_bson_validate_key (void)
+{
+ gboolean valid;
+
+ valid = bson_validate_key (NULL, FALSE, FALSE);
+ ok (valid == FALSE && errno == EINVAL,
+ "bson_validate_key() sets errno when the key is NULL");
+
+ valid = bson_validate_key ("$foo.bar", FALSE, FALSE);
+ ok (valid == TRUE,
+ "bson_validate_key() returns success if both checks are off");
+
+ valid = bson_validate_key ("$foo.bar", FALSE, TRUE);
+ ok (valid == FALSE,
+ "bson_validate_key() returns failiure if the key starts with a $");
+ valid = bson_validate_key ("foo.bar$", FALSE, TRUE);
+ ok (valid == TRUE,
+ "bson_validate_key() returns success if the key does not start with a $");
+
+ valid = bson_validate_key ("foo.bar", TRUE, TRUE);
+ ok (valid == FALSE,
+ "bson_validate_key() returns failiure if the key contains a dot");
+ valid = bson_validate_key ("foobar", TRUE, TRUE);
+ ok (valid == TRUE,
+ "bson_validate_key() returns success if the key does not contain a dot");
+}
+
+RUN_TEST (6, bson_validate_key)