summaryrefslogtreecommitdiffstats
path: root/toolkit/components/ctypes/tests/unit/test_finalizer_shouldaccept.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/ctypes/tests/unit/test_finalizer_shouldaccept.js')
-rw-r--r--toolkit/components/ctypes/tests/unit/test_finalizer_shouldaccept.js174
1 files changed, 174 insertions, 0 deletions
diff --git a/toolkit/components/ctypes/tests/unit/test_finalizer_shouldaccept.js b/toolkit/components/ctypes/tests/unit/test_finalizer_shouldaccept.js
new file mode 100644
index 000000000..f683008e4
--- /dev/null
+++ b/toolkit/components/ctypes/tests/unit/test_finalizer_shouldaccept.js
@@ -0,0 +1,174 @@
+try {
+ // We might be running without privileges, in which case it's up to the
+ // harness to give us the 'ctypes' object.
+ Components.utils.import("resource://gre/modules/ctypes.jsm");
+} catch (e) {
+}
+
+var acquire, dispose, reset_errno, dispose_errno,
+ acquire_ptr, dispose_ptr,
+ acquire_void_ptr, dispose_void_ptr,
+ acquire_string, dispose_string;
+
+function run_test()
+{
+ let library = open_ctypes_test_lib();
+
+ let start = library.declare("test_finalizer_start", ctypes.default_abi,
+ ctypes.void_t,
+ ctypes.size_t);
+ let stop = library.declare("test_finalizer_stop", ctypes.default_abi,
+ ctypes.void_t);
+ let tester = new ResourceTester(start, stop);
+ acquire = library.declare("test_finalizer_acq_size_t",
+ ctypes.default_abi,
+ ctypes.size_t,
+ ctypes.size_t);
+ dispose = library.declare("test_finalizer_rel_size_t",
+ ctypes.default_abi,
+ ctypes.void_t,
+ ctypes.size_t);
+ reset_errno = library.declare("reset_errno",
+ ctypes.default_abi,
+ ctypes.void_t);
+ dispose_errno = library.declare("test_finalizer_rel_size_t_set_errno",
+ ctypes.default_abi,
+ ctypes.void_t,
+ ctypes.size_t);
+ acquire_ptr = library.declare("test_finalizer_acq_int32_ptr_t",
+ ctypes.default_abi,
+ ctypes.int32_t.ptr,
+ ctypes.size_t);
+ dispose_ptr = library.declare("test_finalizer_rel_int32_ptr_t",
+ ctypes.default_abi,
+ ctypes.void_t,
+ ctypes.int32_t.ptr);
+ acquire_string = library.declare("test_finalizer_acq_string_t",
+ ctypes.default_abi,
+ ctypes.char.ptr,
+ ctypes.size_t);
+ dispose_string = library.declare("test_finalizer_rel_string_t",
+ ctypes.default_abi,
+ ctypes.void_t,
+ ctypes.char.ptr);
+
+ tester.launch(10, test_to_string);
+ tester.launch(10, test_to_source);
+ tester.launch(10, test_to_int);
+ tester.launch(10, test_errno);
+ tester.launch(10, test_to_pointer);
+ tester.launch(10, test_readstring);
+}
+
+/**
+ * Check that toString succeeds before/after forget/dispose.
+ */
+function test_to_string()
+{
+ do_print("Starting test_to_string");
+ let a = ctypes.CDataFinalizer(acquire(0), dispose);
+ do_check_eq(a.toString(), "0");
+
+ a.forget();
+ do_check_eq(a.toString(), "[CDataFinalizer - empty]");
+
+ a = ctypes.CDataFinalizer(acquire(0), dispose);
+ a.dispose();
+ do_check_eq(a.toString(), "[CDataFinalizer - empty]");
+}
+
+/**
+ * Check that toSource succeeds before/after forget/dispose.
+ */
+function test_to_source()
+{
+ do_print("Starting test_to_source");
+ let value = acquire(0);
+ let a = ctypes.CDataFinalizer(value, dispose);
+ do_check_eq(a.toSource(),
+ "ctypes.CDataFinalizer("
+ + ctypes.size_t(value).toSource()
+ +", "
+ +dispose.toSource()
+ +")");
+ value = null;
+
+ a.forget();
+ do_check_eq(a.toSource(), "ctypes.CDataFinalizer()");
+
+ a = ctypes.CDataFinalizer(acquire(0), dispose);
+ a.dispose();
+ do_check_eq(a.toSource(), "ctypes.CDataFinalizer()");
+}
+
+/**
+ * Test conversion to int32
+ */
+function test_to_int()
+{
+ let value = 2;
+ let wrapped, converted, finalizable;
+ wrapped = ctypes.int32_t(value);
+ finalizable = ctypes.CDataFinalizer(acquire(value), dispose);
+ converted = ctypes.int32_t(finalizable);
+
+ structural_check_eq(converted, wrapped);
+ structural_check_eq(converted, ctypes.int32_t(finalizable.forget()));
+
+ finalizable = ctypes.CDataFinalizer(acquire(value), dispose);
+ wrapped = ctypes.int64_t(value);
+ converted = ctypes.int64_t(finalizable);
+ structural_check_eq(converted, wrapped);
+ finalizable.dispose();
+}
+
+/**
+ * Test that dispose can change errno but finalization cannot
+ */
+function test_errno(size, tc, cleanup)
+{
+ reset_errno();
+ do_check_eq(ctypes.errno, 0);
+
+ let finalizable = ctypes.CDataFinalizer(acquire(3), dispose_errno);
+ finalizable.dispose();
+ do_check_eq(ctypes.errno, 10);
+ reset_errno();
+
+ do_check_eq(ctypes.errno, 0);
+ for (let i = 0; i < size; ++i) {
+ finalizable = ctypes.CDataFinalizer(acquire(i), dispose_errno);
+ cleanup.add(finalizable);
+ }
+
+ trigger_gc();
+ do_check_eq(ctypes.errno, 0);
+}
+
+/**
+ * Check that a finalizable of a pointer can be used as a pointer
+ */
+function test_to_pointer()
+{
+ let ptr = ctypes.int32_t(2).address();
+ let finalizable = ctypes.CDataFinalizer(ptr, dispose_ptr);
+ let unwrapped = ctypes.int32_t.ptr(finalizable);
+
+ do_check_eq(""+ptr, ""+unwrapped);
+
+ finalizable.forget(); // Do not dispose: This is not a real pointer.
+}
+
+/**
+ * Test that readstring can be applied to a finalizer
+ */
+function test_readstring(size)
+{
+ for (let i = 0; i < size; ++i) {
+ let acquired = acquire_string(i);
+ let finalizable = ctypes.CDataFinalizer(acquired,
+ dispose_string);
+ do_check_eq(finalizable.readString(), acquired.readString());
+ finalizable.dispose();
+ }
+}