test_xpcomutils.js (8505B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- 2 * vim: sw=4 ts=4 sts=4 et 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /** 8 * This file tests the methods on XPCOMUtils.sys.mjs. 9 */ 10 11 const {AppConstants} = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs"); 12 const {ComponentUtils} = ChromeUtils.importESModule("resource://gre/modules/ComponentUtils.sys.mjs"); 13 const {Preferences} = ChromeUtils.importESModule("resource://gre/modules/Preferences.sys.mjs"); 14 const {TestUtils} = ChromeUtils.importESModule("resource://testing-common/TestUtils.sys.mjs"); 15 const {XPCOMUtils} = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs"); 16 17 //////////////////////////////////////////////////////////////////////////////// 18 //// Tests 19 20 add_test(function test_generateQI_string_names() 21 { 22 var x = { 23 QueryInterface: ChromeUtils.generateQI([ 24 "nsIClassInfo", 25 "nsIObserver" 26 ]) 27 }; 28 29 try { 30 x.QueryInterface(Ci.nsIClassInfo); 31 } catch(e) { 32 do_throw("Should QI to nsIClassInfo"); 33 } 34 try { 35 x.QueryInterface(Ci.nsIObserver); 36 } catch(e) { 37 do_throw("Should QI to nsIObserver"); 38 } 39 try { 40 x.QueryInterface(Ci.nsIObserverService); 41 do_throw("QI should not have succeeded!"); 42 } catch(e) {} 43 run_next_test(); 44 }); 45 46 add_test(function test_defineLazyServiceGetter() 47 { 48 let obj = { }; 49 XPCOMUtils.defineLazyServiceGetter(obj, "service", 50 "@mozilla.org/consoleservice;1", 51 Ci.nsIConsoleService); 52 let service = Cc["@mozilla.org/consoleservice;1"]. 53 getService(Ci.nsIConsoleService); 54 55 // Check that the lazy service getter and the actual service have the same 56 // properties. 57 for (let prop in obj.service) 58 Assert.ok(prop in service); 59 for (let prop in service) 60 Assert.ok(prop in obj.service); 61 run_next_test(); 62 }); 63 64 65 add_test(function test_defineLazyPreferenceGetter() 66 { 67 const PREF = "xpcomutils.test.pref"; 68 69 let obj = {}; 70 XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "defaultValue"); 71 72 73 equal(obj.pref, "defaultValue", "Should return the default value before pref is set"); 74 75 Preferences.set(PREF, "currentValue"); 76 77 78 info("Create second getter on new object"); 79 80 obj = {}; 81 XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "defaultValue"); 82 83 84 equal(obj.pref, "currentValue", "Should return the current value on initial read when pref is already set"); 85 86 Preferences.set(PREF, "newValue"); 87 88 equal(obj.pref, "newValue", "Should return new value after preference change"); 89 90 Preferences.set(PREF, "currentValue"); 91 92 equal(obj.pref, "currentValue", "Should return new value after second preference change"); 93 94 95 Preferences.reset(PREF); 96 97 equal(obj.pref, "defaultValue", "Should return default value after pref is reset"); 98 99 obj = {}; 100 XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "a,b", 101 null, value => value.split(",")); 102 103 deepEqual(obj.pref, ["a", "b"], "transform is applied to default value"); 104 105 Preferences.set(PREF, "x,y,z"); 106 deepEqual(obj.pref, ["x", "y", "z"], "transform is applied to updated value"); 107 108 Preferences.reset(PREF); 109 deepEqual(obj.pref, ["a", "b"], "transform is applied to reset default"); 110 111 if (AppConstants.DEBUG) { 112 // Need to use a 'real' pref so it will have a valid prefType 113 obj = {}; 114 Assert.throws( 115 () => XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", "javascript.enabled", 1), 116 /Default value does not match preference type/, 117 "Providing a default value of a different type than the preference throws an exception" 118 ); 119 } 120 121 run_next_test(); 122 }); 123 124 125 add_test(function test_categoryRegistration() 126 { 127 const CATEGORY_NAME = "test-cat"; 128 const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1"; 129 const XULAPPINFO_CID = Components.ID("{fc937916-656b-4fb3-a395-8c63569e27a8}"); 130 131 // Create a fake app entry for our category registration apps filter. 132 let { newAppInfo } = ChromeUtils.importESModule("resource://testing-common/AppInfo.sys.mjs"); 133 let XULAppInfo = newAppInfo({ 134 name: "catRegTest", 135 ID: "{adb42a9a-0d19-4849-bf4d-627614ca19be}", 136 version: "1", 137 platformVersion: "", 138 }); 139 let XULAppInfoFactory = { 140 createInstance: function (iid) { 141 return XULAppInfo.QueryInterface(iid); 142 } 143 }; 144 let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 145 registrar.registerFactory( 146 XULAPPINFO_CID, 147 "XULAppInfo", 148 XULAPPINFO_CONTRACTID, 149 XULAppInfoFactory 150 ); 151 152 // Load test components. 153 do_load_manifest("CatRegistrationComponents.manifest"); 154 155 const expectedEntries = new Map([ 156 ["CatRegisteredComponent", "@unit.test.com/cat-registered-component;1"], 157 ["CatAppRegisteredComponent", "@unit.test.com/cat-app-registered-component;1"], 158 ]); 159 160 // Verify the correct entries are registered in the "test-cat" category. 161 for (let {entry, value} of Services.catMan.enumerateCategory(CATEGORY_NAME)) { 162 ok(expectedEntries.has(entry), `${entry} is expected`); 163 Assert.equal(value, expectedEntries.get(entry), "${entry} has correct value."); 164 expectedEntries.delete(entry); 165 } 166 Assert.deepEqual( 167 Array.from(expectedEntries.keys()), 168 [], 169 "All expected entries have been deleted." 170 ); 171 run_next_test(); 172 }); 173 174 add_test(function test_categoryBackgroundTaskRegistration() 175 { 176 const CATEGORY_NAME = "test-cat1"; 177 178 // Note that this test should succeed whether or not MOZ_BACKGROUNDTASKS is 179 // defined. If it's defined, there's no active task so the `backgroundtask` 180 // directive is processed, dropped, and always succeeds. If it's not defined, 181 // then the `backgroundtask` directive is processed and ignored. 182 183 // Load test components. 184 do_load_manifest("CatBackgroundTaskRegistrationComponents.manifest"); 185 186 let expectedEntriesList = [ 187 ["Cat1RegisteredComponent", "@unit.test.com/cat1-registered-component;1"], 188 ["Cat1BackgroundTaskNotRegisteredComponent", "@unit.test.com/cat1-backgroundtask-notregistered-component;1"], 189 ]; 190 if (!AppConstants.MOZ_BACKGROUNDTASKS) { 191 expectedEntriesList.push(...[ 192 ["Cat1BackgroundTaskRegisteredComponent", "@unit.test.com/cat1-backgroundtask-registered-component;1"], 193 ["Cat1BackgroundTaskAlwaysRegisteredComponent", "@unit.test.com/cat1-backgroundtask-alwaysregistered-component;1"], 194 ]); 195 } 196 const expectedEntries = new Map(expectedEntriesList); 197 198 // Verify the correct entries are registered in the "test-cat" category. 199 for (let {entry, value} of Services.catMan.enumerateCategory(CATEGORY_NAME)) { 200 ok(expectedEntries.has(entry), `${entry} is expected`); 201 Assert.equal(value, expectedEntries.get(entry), "Verify that the value is correct in the expected entries."); 202 expectedEntries.delete(entry); 203 } 204 Assert.deepEqual( 205 Array.from(expectedEntries.keys()), 206 [], 207 "All expected entries have been deleted." 208 ); 209 run_next_test(); 210 }); 211 212 add_test(function test_generateSingletonFactory() 213 { 214 const XPCCOMPONENT_CONTRACTID = "@mozilla.org/singletonComponentTest;1"; 215 const XPCCOMPONENT_CID = Components.ID("{31031c36-5e29-4dd9-9045-333a5d719a3e}"); 216 217 function XPCComponent() {} 218 XPCComponent.prototype = { 219 classID: XPCCOMPONENT_CID, 220 QueryInterface: ChromeUtils.generateQI([]) 221 }; 222 let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 223 registrar.registerFactory( 224 XPCCOMPONENT_CID, 225 "XPCComponent", 226 XPCCOMPONENT_CONTRACTID, 227 ComponentUtils.generateSingletonFactory(XPCComponent) 228 ); 229 230 // First, try to instance the component. 231 let instance = Cc[XPCCOMPONENT_CONTRACTID].createInstance(Ci.nsISupports); 232 // Try again, check that it returns the same instance as before. 233 Assert.equal(instance, 234 Cc[XPCCOMPONENT_CONTRACTID].createInstance(Ci.nsISupports)); 235 // Now, for sanity, check that getService is also returning the same instance. 236 Assert.equal(instance, 237 Cc[XPCCOMPONENT_CONTRACTID].getService(Ci.nsISupports)); 238 239 run_next_test(); 240 }); 241 242 //////////////////////////////////////////////////////////////////////////////// 243 //// Test Runner 244 245 function run_test() 246 { 247 run_next_test(); 248 }