1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/tests/unit/test_tearoffs.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,108 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Cc = Components.classes; 1.9 +const Ci = Components.interfaces; 1.10 + 1.11 +function run_test() { 1.12 + 1.13 + // Load the component manifest containing our test interface implementations. 1.14 + Components.manager.autoRegister(do_get_file('../components/js/xpctest.manifest')); 1.15 + 1.16 + // Shortcut the interfaces we're using. 1.17 + var ifs = { 1.18 + a: Ci['nsIXPCTestInterfaceA'], 1.19 + b: Ci['nsIXPCTestInterfaceB'], 1.20 + c: Ci['nsIXPCTestInterfaceC'] 1.21 + }; 1.22 + 1.23 + // Shortcut the class we're instantiating. This implements all three interfaces. 1.24 + var cls = Cc["@mozilla.org/js/xpc/test/js/TestInterfaceAll;1"]; 1.25 + 1.26 + // Run through the logic a few times. 1.27 + for (i = 0; i < 2; ++i) 1.28 + play_with_tearoffs(ifs, cls); 1.29 +} 1.30 + 1.31 +function play_with_tearoffs(ifs, cls) { 1.32 + 1.33 + // Allocate a bunch of objects, QI-ed to B. 1.34 + var instances = []; 1.35 + for (var i = 0; i < 300; ++i) 1.36 + instances.push(cls.createInstance(ifs.b)); 1.37 + 1.38 + // Nothing to collect. 1.39 + gc(); 1.40 + 1.41 + // QI them to A. 1.42 + instances.forEach(function(v, i, a) { v.QueryInterface(ifs.a); }); 1.43 + 1.44 + // QI them to C. 1.45 + instances.forEach(function(v, i, a) { v.QueryInterface(ifs.c); }); 1.46 + 1.47 + // Check 1.48 + do_check_true('name' in instances[10], 'Have the prop from A/B'); 1.49 + do_check_true('someInteger' in instances[10], 'Have the prop from C'); 1.50 + 1.51 + // Grab tearoff reflections for a and b. 1.52 + var aTearOffs = instances.map(function(v, i, a) { return v.nsIXPCTestInterfaceA; } ); 1.53 + var bTearOffs = instances.map(function(v, i, a) { return v.nsIXPCTestInterfaceB; } ); 1.54 + 1.55 + // Check 1.56 + do_check_true('name' in aTearOffs[1], 'Have the prop from A'); 1.57 + do_check_true(!('someInteger' in aTearOffs[1]), 'Dont have the prop from C'); 1.58 + 1.59 + // Nothing to collect. 1.60 + gc(); 1.61 + 1.62 + // Null out every even instance pointer. 1.63 + for (var i = 0; i < instances.length; ++i) 1.64 + if (i % 2 == 0) 1.65 + instances[i] = null; 1.66 + 1.67 + // Nothing to collect, since we still have the A and B tearoff reflections. 1.68 + gc(); 1.69 + 1.70 + // Null out A tearoff reflections that are a multiple of 3. 1.71 + for (var i = 0; i < aTearOffs.length; ++i) 1.72 + if (i % 3 == 0) 1.73 + aTearOffs[i] = null; 1.74 + 1.75 + // Nothing to collect, since we still have the B tearoff reflections. 1.76 + gc(); 1.77 + 1.78 + // Null out B tearoff reflections that are a multiple of 5. 1.79 + for (var i = 0; i < bTearOffs.length; ++i) 1.80 + if (i % 5 == 0) 1.81 + bTearOffs[i] = null; 1.82 + 1.83 + // This should collect every 30th object (indices that are multiples of 2, 3, and 5). 1.84 + gc(); 1.85 + 1.86 + // Kill the b tearoffs entirely. 1.87 + bTearOffs = 0; 1.88 + 1.89 + // Collect more. 1.90 + gc(); 1.91 + 1.92 + // Get C tearoffs. 1.93 + var cTearOffs = instances.map(function(v, i, a) { return v ? v.nsIXPCTestInterfaceC : null; } ); 1.94 + 1.95 + // Check. 1.96 + do_check_true(!('name' in cTearOffs[1]), 'Dont have the prop from A'); 1.97 + do_check_true('someInteger' in cTearOffs[1], 'have the prop from C'); 1.98 + 1.99 + // Null out the a tearoffs. 1.100 + aTearOffs = null; 1.101 + 1.102 + // Collect all even indices. 1.103 + gc(); 1.104 + 1.105 + // Collect all indices. 1.106 + instances = null; 1.107 + gc(); 1.108 + 1.109 + // Give ourselves a pat on the back. :-) 1.110 + do_check_true(true, "Got all the way through without crashing!"); 1.111 +}