diff options
Diffstat (limited to 'toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js')
-rw-r--r-- | toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js b/toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js new file mode 100644 index 000000000..ffbe1b613 --- /dev/null +++ b/toolkit/components/ctypes/tests/unit/test_finalizer_shouldfail.js @@ -0,0 +1,176 @@ +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, null_dispose, compare, dispose_64; + +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); + compare = library.declare("test_finalizer_cmp_size_t", + ctypes.default_abi, + ctypes.bool, + ctypes.size_t, + ctypes.size_t); + + dispose_64 = library.declare("test_finalizer_rel_int64_t", + ctypes.default_abi, + ctypes.void_t, + ctypes.int64_t); + + let type_afun = ctypes.FunctionType(ctypes.default_abi, + ctypes.void_t, + [ctypes.size_t]).ptr; + + let null_dispose_maker = + library.declare("test_finalizer_rel_null_function", + ctypes.default_abi, + type_afun + ); + null_dispose = null_dispose_maker(); + + tester.launch(10, test_double_dispose); + tester.launch(10, test_finalize_bad_construction); + tester.launch(10, test_null_dispose); + tester.launch(10, test_pass_disposed); + tester.launch(10, test_wrong_type); +} + + +/** + * Testing construction of finalizers with wrong arguments. + */ +function test_finalize_bad_construction() { + // First argument does not match second + must_throw(function() { ctypes.CDataFinalizer({}, dispose); }); + must_throw(function() { ctypes.CDataFinalizer(dispose, dispose); }); + + // Not enough arguments + must_throw(function() { ctypes.CDataFinalizer(init(0)); }); + + // Too many arguments + must_throw(function() { ctypes.CDataFinalizer(init(0), dispose, dispose); }); + + // Second argument is null + must_throw(function() { ctypes.CDataFinalizer(init(0), null); }); + + // Second argument is undefined + must_throw(function() { + let a; + ctypes.CDataFinalizer(init(0), a); + }); + +} + +/** + * Test that forget/dispose can only take place once. + */ +function test_double_dispose() { + function test_one_combination(i, a, b) { + let v = ctypes.CDataFinalizer(acquire(i), dispose); + a(v); + must_throw(function() { b(v); } ); + } + + let call_dispose = function(v) { + v.dispose(); + }; + let call_forget = function(v) { + v.forget(); + }; + + test_one_combination(0, call_dispose, call_dispose); + test_one_combination(1, call_dispose, call_forget); + test_one_combination(2, call_forget, call_dispose); + test_one_combination(3, call_forget, call_forget); +} + + +/** + * Test that nothing (too) bad happens when the finalizer is NULL + */ +function test_null_dispose() +{ + let exception; + + exception = false; + try { + ctypes.CDataFinalizer(acquire(0), null_dispose); + } catch (x) { + exception = true; + } + do_check_true(exception); +} + +/** + * Test that conversion of a disposed/forgotten CDataFinalizer to a C + * value fails nicely. + */ +function test_pass_disposed() +{ + let exception, v; + + exception = false; + v = ctypes.CDataFinalizer(acquire(0), dispose); + do_check_true(compare(v, 0)); + v.forget(); + + try { + compare(v, 0); + } catch (x) { + exception = true; + } + do_check_true(exception); + + exception = false; + v = ctypes.CDataFinalizer(acquire(0), dispose); + do_check_true(compare(v, 0)); + v.dispose(); + + try { + compare(v, 0); + } catch (x) { + exception = true; + } + do_check_true(exception); + + exception = false; + try { + ctypes.int32_t(ctypes.CDataFinalizer(v, dispose)); + } catch (x) { + exception = true; + } + do_check_true(exception); +} + +function test_wrong_type() +{ + let int32_v = ctypes.int32_t(99); + let exception; + try { + ctypes.CDataFinalizer(int32_v, dispose_64); + } catch (x) { + exception = x; + } + + do_check_true(!!exception); + do_check_eq(exception.constructor.name, "TypeError"); +} |