testing/mochitest/tests/SimpleTest/MockObjects.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:bade354c5565
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 /**
6 * Allows registering a mock XPCOM component, that temporarily replaces the
7 * original one when an object implementing a given ContractID is requested
8 * using createInstance.
9 *
10 * @param aContractID
11 * The ContractID of the component to replace, for example
12 * "@mozilla.org/filepicker;1".
13 *
14 * @param aReplacementCtor
15 * The constructor function for the JavaScript object that will be
16 * created every time createInstance is called. This object must
17 * implement QueryInterface and provide the XPCOM interfaces required by
18 * the specified ContractID (for example
19 * Components.interfaces.nsIFilePicker).
20 */
21
22 function MockObjectRegisterer(aContractID, aReplacementCtor) {
23 this._contractID = aContractID;
24 this._replacementCtor = aReplacementCtor;
25 }
26
27 MockObjectRegisterer.prototype = {
28 /**
29 * Replaces the current factory with one that returns a new mock object.
30 *
31 * After register() has been called, it is mandatory to call unregister() to
32 * restore the original component. Usually, you should use a try-catch block
33 * to ensure that unregister() is called.
34 */
35 register: function MOR_register() {
36 if (this._originalFactory)
37 throw new Exception("Invalid object state when calling register()");
38
39 // Define a factory that creates a new object using the given constructor.
40 var providedConstructor = this._replacementCtor;
41 this._mockFactory = {
42 createInstance: function MF_createInstance(aOuter, aIid) {
43 if (aOuter != null)
44 throw SpecialPowers.Cr.NS_ERROR_NO_AGGREGATION;
45 return new providedConstructor().QueryInterface(aIid);
46 }
47 };
48
49 var retVal = SpecialPowers.swapFactoryRegistration(this._cid, this._contractID, this._mockFactory, this._originalFactory);
50 if ('error' in retVal) {
51 throw new Exception("ERROR: " + retVal.error);
52 } else {
53 this._cid = retVal.cid;
54 this._originalFactory = retVal.originalFactory;
55 }
56 },
57
58 /**
59 * Restores the original factory.
60 */
61 unregister: function MOR_unregister() {
62 if (!this._originalFactory)
63 throw new Exception("Invalid object state when calling unregister()");
64
65 // Free references to the mock factory.
66 SpecialPowers.swapFactoryRegistration(this._cid, this._contractID, this._mockFactory, this._originalFactory);
67
68 // Allow registering a mock factory again later.
69 this._cid = null;
70 this._originalFactory = null;
71 this._mockFactory = null;
72 },
73
74 // --- Private methods and properties ---
75
76 /**
77 * The factory of the component being replaced.
78 */
79 _originalFactory: null,
80
81 /**
82 * The CID under which the mock contractID was registered.
83 */
84 _cid: null,
85
86 /**
87 * The nsIFactory that was automatically generated by this object.
88 */
89 _mockFactory: null
90 }

mercurial